veyron/examples: moving examples into a separate repository
Change-Id: I1600157d4b6c27929400f1df4457565ace245576
diff --git a/examples/GO.PACKAGE b/examples/GO.PACKAGE
deleted file mode 100644
index 5b1258e..0000000
--- a/examples/GO.PACKAGE
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "dependencies": {
- "incoming": [
- {"allow": "veyron/examples/..."},
- {"deny": "..."}
- ]
- }
-}
diff --git a/examples/bank/bank.vdl b/examples/bank/bank.vdl
deleted file mode 100644
index bbefdad..0000000
--- a/examples/bank/bank.vdl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-Package bank implements an application to manipulate virtual money. The client's
-Veyron Identity determines the account they can manipulate. New identity's make
-a new account. Clients can deposit, withdraw, transfer, or query their balance
-in virtual currency.
-*/
-package bank
-
-import "veyron2/security"
-
-// Bank allows clients to store virtual money. Certain implementations can use persistent storage.
-// Uses the client's Veyron Identity to determine account access.
-type Bank interface {
- // Connect causes the bank to bless a new user (string) and return their bank account number (int64). Existing users are not blessed (""), but still receive their account number (int64).
- Connect() (newIdentity string, accountNumber int64, err error) {security.WriteLabel}
-}
-
-// The BankAccount can only be accessed by blessed users
-type BankAccount interface {
- // Deposit adds the amount given to this account.
- Deposit(amount int64) error {security.WriteLabel}
- // Withdraw reduces the amount given from this account.
- Withdraw(amount int64) error {security.WriteLabel}
- // Transfer moves the amount given to the receiver's account.
- Transfer(receiver int64, amount int64) error {security.WriteLabel}
- // Balance returns the amount stored in this account.
- Balance() (int64, error) {security.ReadLabel}
-}
diff --git a/examples/bank/bank.vdl.go b/examples/bank/bank.vdl.go
deleted file mode 100644
index 50649ac..0000000
--- a/examples/bank/bank.vdl.go
+++ /dev/null
@@ -1,457 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: bank.vdl
-
-/*
-Package bank implements an application to manipulate virtual money. The client's
-Veyron Identity determines the account they can manipulate. New identity's make
-a new account. Clients can deposit, withdraw, transfer, or query their balance
-in virtual currency.
-*/
-package bank
-
-import (
- "veyron2/security"
-
- // The non-user imports are prefixed with "_gen_" to prevent collisions.
- _gen_veyron2 "veyron2"
- _gen_context "veyron2/context"
- _gen_ipc "veyron2/ipc"
- _gen_naming "veyron2/naming"
- _gen_vdlutil "veyron2/vdl/vdlutil"
- _gen_wiretype "veyron2/wiretype"
-)
-
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
-const _ = _gen_wiretype.TypeIDInvalid
-
-// Bank allows clients to store virtual money. Certain implementations can use persistent storage.
-// Uses the client's Veyron Identity to determine account access.
-// Bank is the interface the client binds and uses.
-// Bank_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type Bank_ExcludingUniversal interface {
- // Connect causes the bank to bless a new user (string) and return their bank account number (int64). Existing users are not blessed (""), but still receive their account number (int64).
- Connect(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (newIdentity string, accountNumber int64, err error)
-}
-type Bank interface {
- _gen_ipc.UniversalServiceMethods
- Bank_ExcludingUniversal
-}
-
-// BankService is the interface the server implements.
-type BankService interface {
-
- // Connect causes the bank to bless a new user (string) and return their bank account number (int64). Existing users are not blessed (""), but still receive their account number (int64).
- Connect(context _gen_ipc.ServerContext) (newIdentity string, accountNumber int64, err error)
-}
-
-// BindBank returns the client stub implementing the Bank
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindBank(name string, opts ..._gen_ipc.BindOpt) (Bank, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubBank{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerBank creates a new server stub.
-//
-// It takes a regular server implementing the BankService
-// interface, and returns a new server stub.
-func NewServerBank(server BankService) interface{} {
- return &ServerStubBank{
- service: server,
- }
-}
-
-// clientStubBank implements Bank.
-type clientStubBank struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubBank) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubBank) Connect(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (newIdentity string, accountNumber int64, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Connect", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&newIdentity, &accountNumber, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBank) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBank) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBank) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubBank wraps a server that implements
-// BankService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubBank struct {
- service BankService
-}
-
-func (__gen_s *ServerStubBank) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Connect":
- return []interface{}{security.Label(4)}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubBank) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Connect"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "newIdentity", Type: 3},
- {Name: "accountNumber", Type: 37},
- {Name: "err", Type: 65},
- },
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
-
- return result, nil
-}
-
-func (__gen_s *ServerStubBank) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubBank) Connect(call _gen_ipc.ServerCall) (newIdentity string, accountNumber int64, err error) {
- newIdentity, accountNumber, err = __gen_s.service.Connect(call)
- return
-}
-
-// The BankAccount can only be accessed by blessed users
-// BankAccount is the interface the client binds and uses.
-// BankAccount_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type BankAccount_ExcludingUniversal interface {
- // Deposit adds the amount given to this account.
- Deposit(ctx _gen_context.T, amount int64, opts ..._gen_ipc.CallOpt) (err error)
- // Withdraw reduces the amount given from this account.
- Withdraw(ctx _gen_context.T, amount int64, opts ..._gen_ipc.CallOpt) (err error)
- // Transfer moves the amount given to the receiver's account.
- Transfer(ctx _gen_context.T, receiver int64, amount int64, opts ..._gen_ipc.CallOpt) (err error)
- // Balance returns the amount stored in this account.
- Balance(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply int64, err error)
-}
-type BankAccount interface {
- _gen_ipc.UniversalServiceMethods
- BankAccount_ExcludingUniversal
-}
-
-// BankAccountService is the interface the server implements.
-type BankAccountService interface {
-
- // Deposit adds the amount given to this account.
- Deposit(context _gen_ipc.ServerContext, amount int64) (err error)
- // Withdraw reduces the amount given from this account.
- Withdraw(context _gen_ipc.ServerContext, amount int64) (err error)
- // Transfer moves the amount given to the receiver's account.
- Transfer(context _gen_ipc.ServerContext, receiver int64, amount int64) (err error)
- // Balance returns the amount stored in this account.
- Balance(context _gen_ipc.ServerContext) (reply int64, err error)
-}
-
-// BindBankAccount returns the client stub implementing the BankAccount
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindBankAccount(name string, opts ..._gen_ipc.BindOpt) (BankAccount, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubBankAccount{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerBankAccount creates a new server stub.
-//
-// It takes a regular server implementing the BankAccountService
-// interface, and returns a new server stub.
-func NewServerBankAccount(server BankAccountService) interface{} {
- return &ServerStubBankAccount{
- service: server,
- }
-}
-
-// clientStubBankAccount implements BankAccount.
-type clientStubBankAccount struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubBankAccount) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubBankAccount) Deposit(ctx _gen_context.T, amount int64, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Deposit", []interface{}{amount}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBankAccount) Withdraw(ctx _gen_context.T, amount int64, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Withdraw", []interface{}{amount}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBankAccount) Transfer(ctx _gen_context.T, receiver int64, amount int64, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Transfer", []interface{}{receiver, amount}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBankAccount) Balance(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply int64, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Balance", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBankAccount) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBankAccount) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBankAccount) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubBankAccount wraps a server that implements
-// BankAccountService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubBankAccount struct {
- service BankAccountService
-}
-
-func (__gen_s *ServerStubBankAccount) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Deposit":
- return []interface{}{security.Label(4)}, nil
- case "Withdraw":
- return []interface{}{security.Label(4)}, nil
- case "Transfer":
- return []interface{}{security.Label(4)}, nil
- case "Balance":
- return []interface{}{security.Label(2)}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubBankAccount) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Balance"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 37},
- {Name: "", Type: 65},
- },
- }
- result.Methods["Deposit"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "amount", Type: 37},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["Transfer"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "receiver", Type: 37},
- {Name: "amount", Type: 37},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["Withdraw"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "amount", Type: 37},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
-
- return result, nil
-}
-
-func (__gen_s *ServerStubBankAccount) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubBankAccount) Deposit(call _gen_ipc.ServerCall, amount int64) (err error) {
- err = __gen_s.service.Deposit(call, amount)
- return
-}
-
-func (__gen_s *ServerStubBankAccount) Withdraw(call _gen_ipc.ServerCall, amount int64) (err error) {
- err = __gen_s.service.Withdraw(call, amount)
- return
-}
-
-func (__gen_s *ServerStubBankAccount) Transfer(call _gen_ipc.ServerCall, receiver int64, amount int64) (err error) {
- err = __gen_s.service.Transfer(call, receiver, amount)
- return
-}
-
-func (__gen_s *ServerStubBankAccount) Balance(call _gen_ipc.ServerCall) (reply int64, err error) {
- reply, err = __gen_s.service.Balance(call)
- return
-}
diff --git a/examples/bank/bank/main.go b/examples/bank/bank/main.go
deleted file mode 100644
index c01cad2..0000000
--- a/examples/bank/bank/main.go
+++ /dev/null
@@ -1,208 +0,0 @@
-// Binary bank is a bank client that interacts with bankd and pbankd.
-// Users connect to a bank service and can send commands to it.
-package main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "os"
- "strconv"
- "strings"
- "time"
-
- "veyron/examples/bank"
- vsecurity "veyron/security"
- idutil "veyron/services/identity/util"
-
- "veyron2"
- "veyron2/naming"
- "veyron2/rt"
- "veyron2/security"
-)
-
-var (
- // TODO(rthellend): Remove the address flag when the config manager is working.
- address = flag.String("address", "", "the address/endpoint of the bank server")
- serverPattern = flag.String("server_pattern", string(security.AllPrincipals), "server_pattern is an optional pattern for the expected identity of the fortune server. Example: the pattern \"myorg/fortune\" matches identities with names \"myorg/fortune\" or \"myorg\". If the flag is absent then the default pattern \"...\" matches all identities.")
- accountMountTableName string
-)
-
-const bankMountTableName string = "veyron/bank"
-
-// Parses str and returns a nonnegative integer
-func getInt(str string, name string) (int64, bool) {
- v, err := strconv.ParseInt(str, 0, 64)
- if err != nil {
- fmt.Printf("given %s %s was not an integer: %s\n", name, str, err)
- return 0, true
- }
- return v, false
-}
-
-func main() {
- // Create the Veyron runtime using VEYRON_IDENTITY
- runtime := rt.Init()
- log := runtime.Logger()
-
- // Construct a new stub that binds to serverEndpoint without
- // using the name service
- var bankServer bank.Bank
- var err error
- if *address != "" {
- bankServer, err = bank.BindBank(naming.JoinAddressName(*address, "//bank"))
- } else {
- bankServer, err = bank.BindBank("veyron/bank")
- }
- if err != nil {
- log.Fatal("error binding to server: ", err)
- }
-
- ctx, _ := runtime.NewContext().WithTimeout(time.Minute)
-
- // First, Connect to the bank to retrieve the location you should bind to.
- newIdentity, bankAccountNumber, err := bankServer.Connect(ctx, veyron2.RemoteID(*serverPattern))
- if err != nil {
- log.Fatalf("%s.Connect failed: %s\n", bankMountTableName, err)
- }
- fmt.Printf("Successfully connected to the bank with account: %d\n", bankAccountNumber)
-
- client := runtime.Client()
- // If you got a new identity, you should update your PrivateID and make a new client with that identity.
- if newIdentity != "" {
- // Decode the new identity
- var newPublicID security.PublicID
- err := idutil.Base64VomDecode(newIdentity, &newPublicID)
- if err != nil {
- log.Fatalf("failed to decode the given public id: %s\n", err)
- }
-
- // Derive the new PrivateID
- derivedIdentity, err := runtime.Identity().Derive(newPublicID)
- if err != nil {
- log.Fatalf("failed to derive identity: %s\n", err)
- }
-
- // Update the PrivateID at VEYRON_IDENTITY
- path := os.Getenv("VEYRON_IDENTITY")
- f, err := os.OpenFile(path, os.O_WRONLY, 0600)
- if err != nil {
- log.Fatalf("failed to open identity file for writing: %s\n", err)
- }
- err = vsecurity.SaveIdentity(f, derivedIdentity)
- if err != nil {
- log.Fatalf("failed to save identity: %s\n", err)
- }
- err = f.Close()
- if err != nil {
- log.Fatalf("could not close file %q, %s\n", path, err)
- }
-
- // Make a NewClient and update the other one. Do not close the old client; we need its connection to the Mount Table.
- client, err = runtime.NewClient(veyron2.LocalID(newPublicID))
- if err != nil {
- log.Fatalf("failed to create new client: %s\n", err)
- }
- }
-
- // Bind to the bank account service
- accountMountTableName = fmt.Sprintf("veyron/bank/%d", bankAccountNumber)
- bindLocation := fmt.Sprintf("//bank/%d", bankAccountNumber)
- var accountServer bank.BankAccount
- if *address != "" { // Connect directly to the server's endpoint
- accountServer, err = bank.BindBankAccount(naming.JoinAddressName(*address, bindLocation), client)
- } else { // Use the Mount Table to connect to the server
- accountServer, err = bank.BindBankAccount(accountMountTableName, client)
- }
- if err != nil {
- log.Fatalf("error binding to server: ", err)
- }
-
- // Read commands from standard input until the user decides to quit/exit.
- end := false
- for !end {
- fmt.Print("Your command: ")
-
- // Read input from user
- in := bufio.NewReader(os.Stdin)
- input, _ := in.ReadString('\n')
- commands := strings.Fields(input)
-
- if len(commands) == 0 {
- fmt.Println("Please enter a command. 'help' displays the list of commands.")
- continue
- }
-
- switch commands[0] {
- case "bankAccountNumber":
- fmt.Printf("Your bank account number is %d\n", bankAccountNumber)
- case "deposit":
- if len(commands) < 2 {
- fmt.Println("deposit takes an amount")
- break
- }
- amount, e := getInt(commands[1], "amount")
- if e {
- break
- }
- err := accountServer.Deposit(ctx, amount, veyron2.RemoteID(*serverPattern))
- if err != nil {
- fmt.Printf("%s.Deposit failed: %s\n", accountMountTableName, err)
- break
- }
- fmt.Printf("Deposited %d\n", amount)
- case "withdraw":
- if len(commands) < 2 {
- fmt.Println("withdraw takes an amount")
- break
- }
- amount, e := getInt(commands[1], "amount")
- if e {
- break
- }
- err := accountServer.Withdraw(ctx, amount, veyron2.RemoteID(*serverPattern))
- if err != nil {
- fmt.Printf("%s.Withdraw failed: %s\n", accountMountTableName, err)
- break
- }
- fmt.Printf("Withdrew %d\n", amount)
- case "transfer":
- if len(commands) < 3 {
- fmt.Println("transfer takes an account number and an amount")
- break
- }
- accountNumber, e1 := getInt(commands[1], "account number")
- amount, e2 := getInt(commands[2], "amount")
- if e1 || e2 {
- break
- }
- err := accountServer.Transfer(ctx, accountNumber, amount, veyron2.RemoteID(*serverPattern))
- if err != nil {
- fmt.Printf("%s.Transfer failed: %s\n", accountMountTableName, err)
- break
- }
- fmt.Printf("Transferred %d to %d\n", amount, accountNumber)
- case "balance":
- balance, err := accountServer.Balance(ctx, veyron2.RemoteID(*serverPattern))
- if err != nil {
- fmt.Printf("%s.Balance failed: %s\n", accountMountTableName, err)
- break
- }
- fmt.Printf("User has balance %d\n", balance)
- case "help":
- fmt.Println("You can do the following actions:")
- fmt.Println("bankAccountNumber: check your account number")
- fmt.Println("balance: check your account balance")
- fmt.Println("deposit [N>=0]: deposit money into your account")
- fmt.Println("withdraw [N>=0]: withdraw money from your account")
- fmt.Println("transfer [account number] [N>=0]: transfer money to another account")
- fmt.Println("quit: quit the program")
- fmt.Println("exit: also quits the program")
- case "exit", "quit":
- fmt.Println("Quitting...")
- end = true
- default:
- fmt.Printf("Unknown command: %s\n", commands[0])
- }
- }
-}
diff --git a/examples/bank/pbankd/main.go b/examples/bank/pbankd/main.go
deleted file mode 100644
index 1806daa..0000000
--- a/examples/bank/pbankd/main.go
+++ /dev/null
@@ -1,470 +0,0 @@
-// Binary pbankd is a simple implementation of the bank service.
-// Binary bank clients can connect to this bank service to manage virtual bank
-// accounts. Unlike bankd, pbankd uses the Veyron Store. It can recover user
-// data after a crash, but it must always connect to the stored service.
-// Unlike bankd, pbankd prevents race conditions with transactions.
-package main
-
-// ---------------------------------------------------------
-// NOTE(kash): This file is commented out because we are making large changes
-// to the Store API and we don't want to repeatedly update this example.
-// Additionally, the server uses a common transaction across all requests,
-// so there is a pretty bad race condition that we don't want people to
-// copy. The only reason we are keeping this file is because it demonstrates
-// how to write a custom dispatcher.
-// ---------------------------------------------------------
-
-// import (
-// "errors"
-// "flag"
-// "fmt"
-// "math/rand"
-// "os"
-// "os/user"
-// "path/filepath"
-// "reflect"
-// "regexp"
-// "strings"
-// "time"
-
-// "veyron/examples/bank"
-// "veyron/examples/bank/schema"
-// "veyron/lib/signals"
-// vsecurity "veyron/security"
-// "veyron/security/caveat"
-// idutil "veyron/services/identity/util"
-
-// "veyron2"
-// "veyron2/ipc"
-// "veyron2/naming"
-// "veyron2/rt"
-// "veyron2/security"
-// "veyron.io/store/veyron2/storage"
-// "veyron.io/store/veyron2/storage/vstore"
-// "veyron2/vlog"
-// )
-
-// // Duration of a bank account blessing, intended to be very long.
-// const BLESS_DURATION = 24 * 10000 * time.Hour
-
-// // Ensure that account numbers are all 6 digits long.
-// const MIN_ACCOUNT_NUMBER = 100000
-// const MAX_ACCOUNT_NUMBER = 999999
-// const SUFFIX_REGEXP = "/[0-9]{6}"
-
-// // Where we will store the bank in the store database.
-// const BANK_ROOT string = "/Bank"
-
-// var (
-// storeName string
-// ACCOUNTS string
-// runtime veyron2.Runtime
-// )
-
-// func init() {
-// username := "unknown"
-// if u, err := user.Current(); err == nil {
-// username = u.Username
-// }
-// hostname := "unknown"
-// if h, err := os.Hostname(); err == nil {
-// hostname = h
-// }
-// dir := "global/vstore/" + hostname + "/" + username
-
-// // Parse the flags (variableName, flagName, defaultValue, description)
-// flag.StringVar(&storeName, "store", dir, "Name of the Veyron store")
-
-// // Set the random seed to the current time to increase psuedorandomness.
-// rand.Seed(time.Now().Unix())
-
-// // Set the name for the ACCOUNTS 'constant'. TODO(alexfandrianto): Is there a better way to know the field is named "Accounts"?
-// ACCOUNTS = reflect.TypeOf(schema.Bank{}).Field(0).Name
-// }
-
-// // The following struct and functions handle construction of the persistent bank.
-// type pbankd struct {
-// // Pointer to the store
-// store storage.Store
-
-// // Current Transaction name; empty if there's no transaction
-// tname string
-
-// // The bank's private ID (used for blessing)
-// ID security.PrivateID
-// }
-
-// // newPbankd creates a new persistent bank structure.
-// func newPbankd(store storage.Store, identity security.PrivateID) *pbankd {
-// b := &pbankd{
-// store: store,
-// ID: identity,
-// }
-// return b
-// }
-
-// // InitializeBank bank details in the store; currently only initializes the root.
-// func (b *pbankd) initializeBank() {
-// if err := b.newTransaction(); err != nil {
-// vlog.Fatal(err)
-// }
-// // NOTE(sadovsky): initializeBankRoot ought to return an error. Currently,
-// // some errors (e.g. failed puts) could slip through unnoticed.
-// b.initializeBankRoot()
-// if err := b.commit(); err != nil {
-// vlog.Fatal(err)
-// }
-// }
-
-// // initializeBankRoot prepares the bank root as BANK_ROOT if it isn't yet in the Veyron store.
-// func (b *pbankd) initializeBankRoot() {
-// // Create parent directories for the bank root, if necessary
-// l := strings.Split(BANK_ROOT, "/")
-// fmt.Println(l)
-// for i, _ := range l {
-// fmt.Println(i)
-// prefix := filepath.Join(l[:i]...)
-// o := b.store.BindObject(naming.Join(b.tname, prefix))
-// if exist, err := o.Exists(runtime.TODOContext()); err != nil {
-// vlog.Infof("Error checking existence at %q: %s", prefix, err)
-// } else if !exist {
-// if _, err := o.Put(runtime.TODOContext(), &schema.Dir{}); err != nil {
-// vlog.Infof("Error creating parent %q: %s", prefix, err)
-// }
-// fmt.Printf("%q was created!\n", prefix)
-// } else {
-// fmt.Printf("%q was already present in the store.\n", prefix)
-// }
-// }
-
-// // Add the bank schema to the store at BANK_ROOT, if necessary
-// o := b.store.BindObject(naming.Join(b.tname, BANK_ROOT))
-// if exist, err := o.Exists(runtime.TODOContext()); err != nil {
-// vlog.Infof("Error checking existence at %q: %s", BANK_ROOT, err)
-// } else if !exist {
-// _, err := o.Put(runtime.TODOContext(), &schema.Bank{})
-// if err != nil {
-// vlog.Infof("Error creating bank at %q: %s", BANK_ROOT, err)
-// }
-// }
-// }
-
-// // Register creates an account for a new user with the given bankName.
-// func (b *pbankd) Connect(context ipc.ServerContext) (string, int64, error) {
-// // Check if the RemoteID() has been blessed by the bank
-// if num := getBankAccountNumber(context); num != 0 {
-// // Look up the user and return their bank account number
-// fmt.Println("This client is blessed!")
-// fmt.Printf("ID: %d\n", num)
-// return "", num, nil
-// } else {
-// fmt.Println("This client isn't blessed. Let's bless them!")
-// // Use the store
-// if err := b.newTransaction(); err != nil {
-// vlog.Fatal(err)
-// }
-
-// // Keep rolling until we get an unseen number
-// randID := rand.Int63n(MAX_ACCOUNT_NUMBER-MIN_ACCOUNT_NUMBER) + MIN_ACCOUNT_NUMBER
-// for b.isUser(randID) {
-// randID = rand.Int63n(MAX_ACCOUNT_NUMBER-MIN_ACCOUNT_NUMBER) + MIN_ACCOUNT_NUMBER
-// }
-// fmt.Printf("ID: %d\n", randID)
-
-// // Bless the user
-// pp := security.BlessingPattern(context.LocalID().Names()[0])
-// pID, err := b.ID.Bless(
-// context.RemoteID(),
-// fmt.Sprintf("%d", randID),
-// BLESS_DURATION,
-// []security.ServiceCaveat{security.UniversalCaveat(caveat.PeerBlessings{pp})},
-// )
-// if err != nil {
-// vlog.Fatal(err)
-// }
-
-// // Encode the public ID
-// enc, err := idutil.Base64VomEncode(pID)
-// if err != nil {
-// vlog.Fatal(err)
-// }
-
-// // Store the user into the database
-// b.registerNewUser(randID)
-// err = b.commit()
-// if err != nil {
-// vlog.Fatal(err)
-// }
-
-// // Ensure the new user is a user before returning the blessing and ID
-// if b.isUser(randID) {
-// return enc, randID, nil
-// }
-// return "", 0, fmt.Errorf("failed to register user")
-// }
-// }
-
-// // Deposit adds the amount given to this account.
-// func (b *pbankd) Deposit(context ipc.ServerContext, amount int64) error {
-// user := getBankAccountNumber(context)
-// if user == 0 {
-// return fmt.Errorf("couldn't retrieve account number")
-// }
-// if err := b.newTransaction(); err != nil {
-// return err
-// }
-// if !b.isUser(user) {
-// return fmt.Errorf("user isn't registered")
-// } else if amount < 0 {
-// return fmt.Errorf("deposit amount %d is negative", amount)
-// }
-// b.changeBalance(user, amount)
-// return b.commit()
-// }
-
-// // Withdraw reduces the amount given from this account.
-// func (b *pbankd) Withdraw(context ipc.ServerContext, amount int64) error {
-// user := getBankAccountNumber(context)
-// if user == 0 {
-// return fmt.Errorf("couldn't retrieve account number")
-// }
-// if err := b.newTransaction(); err != nil {
-// return err
-// }
-// if !b.isUser(user) {
-// return fmt.Errorf("user isn't registered")
-// } else if amount < 0 {
-// return fmt.Errorf("withdraw amount %d is negative", amount)
-// } else if balance := b.checkBalance(user); amount > balance {
-// return fmt.Errorf("withdraw amount %d exceeds balance %d", amount, balance)
-// }
-// b.changeBalance(user, -amount)
-// return b.commit()
-// }
-
-// // Transfer moves the amount given to the receiver.
-// func (b *pbankd) Transfer(context ipc.ServerContext, accountNumber int64, amount int64) error {
-// user := getBankAccountNumber(context)
-// if user == 0 {
-// return fmt.Errorf("couldn't retrieve account number")
-// }
-// if err := b.newTransaction(); err != nil {
-// return err
-// }
-// if !b.isUser(user) {
-// return fmt.Errorf("user isn't registered")
-// } else if !b.isUser(accountNumber) {
-// return fmt.Errorf("%d isn't registered", accountNumber)
-// } else if amount < 0 {
-// return fmt.Errorf("transfer amount %d is negative", amount)
-// } else if balance := b.checkBalance(user); amount > balance {
-// return fmt.Errorf("transfer amount %d exceeds balance %d", amount, balance)
-// }
-// b.changeBalance(user, -amount)
-// b.changeBalance(accountNumber, amount)
-// return b.commit()
-// }
-
-// // Balance returns the amount stored by the given user.
-// // Throws an error if the user is invalid.
-// func (b *pbankd) Balance(context ipc.ServerContext) (int64, error) {
-// user := getBankAccountNumber(context)
-// if user == 0 {
-// return 0, fmt.Errorf("couldn't retrieve account number")
-// }
-// if !b.isUser(user) {
-// return 0, fmt.Errorf("user isn't registered")
-// }
-// return b.checkBalance(user), nil
-// }
-
-// /*
-// Helper functions for the persistent bank service that deal with store access.
-// */
-
-// // newTransaction starts a new transaction.
-// func (b *pbankd) newTransaction() error {
-// tid, err := b.store.BindTransactionRoot("").CreateTransaction(runtime.TODOContext())
-// if err != nil {
-// b.tname = ""
-// return err
-// }
-// b.tname = tid // Transaction is rooted at "", so tname == tid.
-// return nil
-// }
-
-// // commit commits the current transaction.
-// func (b *pbankd) commit() error {
-// if b.tname == "" {
-// return errors.New("No transaction to commit")
-// }
-// err := b.store.BindTransaction(b.tname).Commit(runtime.TODOContext())
-// b.tname = ""
-// if err != nil {
-// return fmt.Errorf("Failed to commit transaction: %s", err)
-// }
-// return nil
-// }
-
-// // isUser helps determine if the given user is part of the system or not.
-// func (b *pbankd) isUser(accountNumber int64) bool {
-// // If this is a user, their location in the store should exist.
-// prefix := filepath.Join(BANK_ROOT, ACCOUNTS, fmt.Sprintf("%d", accountNumber))
-// o := b.store.BindObject(naming.Join(b.tname, prefix))
-// exist, err := o.Exists(runtime.TODOContext())
-// if err != nil {
-// vlog.Infof("Error checking existence at %s: %s", prefix, err)
-// return false
-// }
-// return exist
-// }
-
-// // Obtains the bank account number of the user. Returns 0 if it could not be found.
-// func getBankAccountNumber(context ipc.ServerContext) int64 {
-// bankName := context.LocalID().Names()[0]
-
-// // Untrusted clients have no names.
-// if len(context.RemoteID().Names()) == 0 {
-// return 0
-// }
-
-// // Otherwise, extract the account number from the name.
-// name := context.RemoteID().Names()[0]
-// if match, err := regexp.MatchString(bankName+SUFFIX_REGEXP, name); err != nil {
-// vlog.Infof("MatchString error: %s", err)
-// return 0
-// } else if !match {
-// vlog.Infof("No matching name found")
-// return 0
-// }
-// var v int64
-// _, err := fmt.Sscanf(name, bankName+"/%d", &v)
-// if err != nil {
-// vlog.Infof("Failure to parse ID from %s: %s", name, err)
-// return 0
-// }
-// return v
-// }
-
-// // registerNewUser adds the user to the system under the specified name and returns success.
-// func (b *pbankd) registerNewUser(user int64) {
-// // Create the user's account
-// prefix := filepath.Join(BANK_ROOT, ACCOUNTS, fmt.Sprintf("%d", user))
-// o := b.store.BindObject(naming.Join(b.tname, prefix))
-// if _, err := o.Put(runtime.TODOContext(), int64(0)); err != nil {
-// vlog.Infof("Error creating %s: %s", prefix, err)
-// }
-// }
-
-// // checkBalance gets the user's balance from the store
-// func (b *pbankd) checkBalance(user int64) int64 {
-// prefix := filepath.Join(BANK_ROOT, ACCOUNTS, fmt.Sprintf("%d", user))
-// o := b.store.BindObject(naming.Join(b.tname, prefix))
-// e, err := o.Get(runtime.TODOContext())
-// if err != nil {
-// vlog.Infof("Error getting %s: %s", prefix, err)
-// }
-// value, _ := e.Value.(int64)
-// return value
-// }
-
-// // changeBalance modifies the user's balance in the store
-// func (b *pbankd) changeBalance(user int64, amount int64) {
-// prefix := filepath.Join(BANK_ROOT, ACCOUNTS, fmt.Sprintf("%d", user))
-// o := b.store.BindObject(naming.Join(b.tname, prefix))
-// e, err := o.Get(runtime.TODOContext())
-// if err != nil {
-// vlog.Infof("Error getting %s: %s", prefix, err)
-// }
-// if _, err := o.Put(runtime.TODOContext(), e.Value.(int64)+amount); err != nil {
-// vlog.Infof("Error changing %s: %s", prefix, err)
-// }
-// }
-
-// // This custom bank dispatcher has two interfaces with distinct authorizers.
-// func newBankDispatcher(bankServer interface{}, bankAccountServer interface{}, authBank security.Authorizer, authBankAccount security.Authorizer) ipc.Dispatcher {
-// return BankDispatcher{ipc.ReflectInvoker(bankServer), ipc.ReflectInvoker(bankAccountServer), authBank, authBankAccount}
-// }
-
-// type BankDispatcher struct {
-// invokerBank ipc.Invoker
-// invokerBankAccount ipc.Invoker
-// authBank security.Authorizer
-// authBankAccount security.Authorizer
-// }
-
-// func (d BankDispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
-// fmt.Println("Dispatcher Lookup Suffix:", suffix)
-// if suffix != "" {
-// return d.invokerBankAccount, d.authBankAccount, nil
-// }
-// return d.invokerBank, d.authBank, nil
-// }
-
-// // The custom account authorizer checks if the RemoteID matches a regexp pattern and allows only Reads and Writes.
-// type AccountAuthorizer string
-
-// func (aa AccountAuthorizer) Authorize(ctx security.Context) error {
-// name := ctx.RemoteID().Names()[0]
-// match, err := regexp.MatchString(string(aa), name)
-// fmt.Printf("Authorizing for Account %s %t\n", name, match)
-// if err != nil {
-// return err
-// }
-// if match {
-// if ctx.Label() != security.ReadLabel && ctx.Label() != security.WriteLabel {
-// return errors.New("unauthorized; may only read or write")
-// }
-// return nil
-// }
-// return errors.New("unauthorized to access account")
-// }
-
-func main() {
- // // Create a new server instance.
- // runtime = rt.Init()
- // s, err := runtime.NewServer()
- // if err != nil {
- // vlog.Fatal("failure creating server: ", err)
- // }
-
- // // Connect to the Veyron Store
- // vlog.Infof("Binding to store on %s", storeName)
- // st, err := vstore.New(storeName)
- // if err != nil {
- // vlog.Fatalf("Can't connect to store: %s: %s", storeName, err)
- // }
-
- // // Create the bank server and bank account server stubs, using the store connection
- // pbankd := newPbankd(st, runtime.Identity())
- // pbankd.initializeBank()
- // bankServer := bank.NewServerBank(pbankd)
- // bankAccountServer := bank.NewServerBankAccount(pbankd)
-
- // // Setup bank and account authorizers.
- // bankAuth := vsecurity.NewACLAuthorizer(security.ACL{In:
- // map[security.BlessingPattern]security.LabelSet{
- // security.AllPrincipals: security.LabelSet(security.ReadLabel | security.WriteLabel),
- // }})
- // bankAccountAuth := AccountAuthorizer(runtime.Identity().PublicID().Names()[0] + SUFFIX_REGEXP)
-
- // dispatcher := newBankDispatcher(bankServer, bankAccountServer, bankAuth, bankAccountAuth)
-
- // // Create an endpoint and begin listening.
- // endpoint, err := s.Listen("tcp", "127.0.0.1:0")
- // if err == nil {
- // fmt.Printf("Listening at: %v\n", endpoint)
- // } else {
- // vlog.Fatal("error listening to service: ", err)
- // }
-
- // // Publish the service in the mount table.
- // mountName := "veyron/bank"
- // fmt.Printf("Mounting bank on %s, endpoint /%s\n", mountName, endpoint)
- // if err := s.Serve(mountName, dispatcher); err != nil {
- // vlog.Fatal("s.Serve() failed: ", err)
- // }
-
- // // Wait forever.
- // <-signals.ShutdownOnSignals()
-}
diff --git a/examples/bank/schema/init.go b/examples/bank/schema/init.go
deleted file mode 100644
index 2040e0f..0000000
--- a/examples/bank/schema/init.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// This schema registers structs used in the bank example to the VOM for the Veyron store.
-package schema
-
-import (
- "veyron2/vom"
-)
-
-func init() {
- vom.Register(&Dir{})
- vom.Register(&Bank{})
-}
diff --git a/examples/bank/schema/schema.vdl b/examples/bank/schema/schema.vdl
deleted file mode 100644
index 2614d00..0000000
--- a/examples/bank/schema/schema.vdl
+++ /dev/null
@@ -1,9 +0,0 @@
-package schema
-
-// Dir is used to represent directories.
-type Dir struct{}
-
-// Bank is used to represent the information stored in a bank.
-type Bank struct {
- Accounts map[string]int64
-}
diff --git a/examples/bank/schema/schema.vdl.go b/examples/bank/schema/schema.vdl.go
deleted file mode 100644
index 78fd25d..0000000
--- a/examples/bank/schema/schema.vdl.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: schema.vdl
-
-package schema
-
-// Dir is used to represent directories.
-type Dir struct {
-}
-
-// Bank is used to represent the information stored in a bank.
-type Bank struct {
- Accounts map[string]int64
-}
diff --git a/examples/boxes/android/build.sh b/examples/boxes/android/build.sh
deleted file mode 100755
index a3450a9..0000000
--- a/examples/boxes/android/build.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-
-source "${VEYRON_ROOT}/environment/scripts/lib/shell.sh"
-
-main() {
- # Path of the go binary that was built with the goandroid patches.
- local -r GOANDROID="$1"
-
- # Path of where eclipse installs the libs for the DragAndDraw
- # android app.
- local -r SHAREDLIB="$2"
-
- local -r ANDROID_CC="${NDK_ROOT}/bin/arm-linux-androideabi-gcc"
- local ANDROID_LDFLAGS="-android -shared -extld ${CC} -extldflags"
- ANDROID_LDFLAGS+=" '-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16'"
- CC="${ANDROID_CC}" GOPATH="`pwd`:${GOPATH}" GOROOT="" GOOS=linux \
- GOARCH=arm GOARM=7 CGO_ENABLED=1 "${GOANDROID}" install "${GOFLAGS}" \
- -v -ldflags="${ANDROID_LDFLAGS}" -tags android boxesp2p
- cp bin/linux_arm/boxesp2p "${SHAREDLIB}"
-}
-
-main "$@"
diff --git a/examples/boxes/android/src/boxesp2p/jni.h b/examples/boxes/android/src/boxesp2p/jni.h
deleted file mode 100644
index 262c137..0000000
--- a/examples/boxes/android/src/boxesp2p/jni.h
+++ /dev/null
@@ -1,1157 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-/*
- * JNI specification, as defined by Sun:
- * http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html
- *
- * Everything here is expected to be VM-neutral.
- */
-
-#ifndef JNI_H_
-#define JNI_H_
-
-#include <sys/cdefs.h>
-#include <stdarg.h>
-
-/*
- * Primitive types that match up with Java equivalents.
- */
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h> /* C99 */
-typedef uint8_t jboolean; /* unsigned 8 bits */
-typedef int8_t jbyte; /* signed 8 bits */
-typedef uint16_t jchar; /* unsigned 16 bits */
-typedef int16_t jshort; /* signed 16 bits */
-typedef int32_t jint; /* signed 32 bits */
-typedef int64_t jlong; /* signed 64 bits */
-typedef float jfloat; /* 32-bit IEEE 754 */
-typedef double jdouble; /* 64-bit IEEE 754 */
-#else
-typedef unsigned char jboolean; /* unsigned 8 bits */
-typedef signed char jbyte; /* signed 8 bits */
-typedef unsigned short jchar; /* unsigned 16 bits */
-typedef short jshort; /* signed 16 bits */
-typedef int jint; /* signed 32 bits */
-typedef long long jlong; /* signed 64 bits */
-typedef float jfloat; /* 32-bit IEEE 754 */
-typedef double jdouble; /* 64-bit IEEE 754 */
-#endif
-
-/* "cardinal indices and sizes" */
-typedef jint jsize;
-
-#ifdef __cplusplus
-/*
- * Reference types, in C++
- */
-class _jobject {};
-class _jclass : public _jobject {};
-class _jstring : public _jobject {};
-class _jarray : public _jobject {};
-class _jobjectArray : public _jarray {};
-class _jbooleanArray : public _jarray {};
-class _jbyteArray : public _jarray {};
-class _jcharArray : public _jarray {};
-class _jshortArray : public _jarray {};
-class _jintArray : public _jarray {};
-class _jlongArray : public _jarray {};
-class _jfloatArray : public _jarray {};
-class _jdoubleArray : public _jarray {};
-class _jthrowable : public _jobject {};
-
-typedef _jobject* jobject;
-typedef _jclass* jclass;
-typedef _jstring* jstring;
-typedef _jarray* jarray;
-typedef _jobjectArray* jobjectArray;
-typedef _jbooleanArray* jbooleanArray;
-typedef _jbyteArray* jbyteArray;
-typedef _jcharArray* jcharArray;
-typedef _jshortArray* jshortArray;
-typedef _jintArray* jintArray;
-typedef _jlongArray* jlongArray;
-typedef _jfloatArray* jfloatArray;
-typedef _jdoubleArray* jdoubleArray;
-typedef _jthrowable* jthrowable;
-typedef _jobject* jweak;
-
-
-#else /* not __cplusplus */
-
-/*
- * Reference types, in C.
- */
-typedef void* jobject;
-typedef jobject jclass;
-typedef jobject jstring;
-typedef jobject jarray;
-typedef jarray jobjectArray;
-typedef jarray jbooleanArray;
-typedef jarray jbyteArray;
-typedef jarray jcharArray;
-typedef jarray jshortArray;
-typedef jarray jintArray;
-typedef jarray jlongArray;
-typedef jarray jfloatArray;
-typedef jarray jdoubleArray;
-typedef jobject jthrowable;
-typedef jobject jweak;
-
-#endif /* not __cplusplus */
-
-struct _jfieldID; /* opaque structure */
-typedef struct _jfieldID* jfieldID; /* field IDs */
-
-struct _jmethodID; /* opaque structure */
-typedef struct _jmethodID* jmethodID; /* method IDs */
-
-struct JNIInvokeInterface;
-
-typedef union jvalue {
- jboolean z;
- jbyte b;
- jchar c;
- jshort s;
- jint i;
- jlong j;
- jfloat f;
- jdouble d;
- jobject l;
-} jvalue;
-
-typedef enum jobjectRefType {
- JNIInvalidRefType = 0,
- JNILocalRefType = 1,
- JNIGlobalRefType = 2,
- JNIWeakGlobalRefType = 3
-} jobjectRefType;
-
-typedef struct {
- const char* name;
- const char* signature;
- void* fnPtr;
-} JNINativeMethod;
-
-struct _JNIEnv;
-struct _JavaVM;
-typedef const struct JNINativeInterface* C_JNIEnv;
-
-#if defined(__cplusplus)
-typedef _JNIEnv JNIEnv;
-typedef _JavaVM JavaVM;
-#else
-typedef const struct JNINativeInterface* JNIEnv;
-typedef const struct JNIInvokeInterface* JavaVM;
-#endif
-
-/*
- * Table of interface function pointers.
- */
-struct JNINativeInterface {
- void* reserved0;
- void* reserved1;
- void* reserved2;
- void* reserved3;
-
- jint (*GetVersion)(JNIEnv *);
-
- jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,
- jsize);
- jclass (*FindClass)(JNIEnv*, const char*);
-
- jmethodID (*FromReflectedMethod)(JNIEnv*, jobject);
- jfieldID (*FromReflectedField)(JNIEnv*, jobject);
- /* spec doesn't show jboolean parameter */
- jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean);
-
- jclass (*GetSuperclass)(JNIEnv*, jclass);
- jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass);
-
- /* spec doesn't show jboolean parameter */
- jobject (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean);
-
- jint (*Throw)(JNIEnv*, jthrowable);
- jint (*ThrowNew)(JNIEnv *, jclass, const char *);
- jthrowable (*ExceptionOccurred)(JNIEnv*);
- void (*ExceptionDescribe)(JNIEnv*);
- void (*ExceptionClear)(JNIEnv*);
- void (*FatalError)(JNIEnv*, const char*);
-
- jint (*PushLocalFrame)(JNIEnv*, jint);
- jobject (*PopLocalFrame)(JNIEnv*, jobject);
-
- jobject (*NewGlobalRef)(JNIEnv*, jobject);
- void (*DeleteGlobalRef)(JNIEnv*, jobject);
- void (*DeleteLocalRef)(JNIEnv*, jobject);
- jboolean (*IsSameObject)(JNIEnv*, jobject, jobject);
-
- jobject (*NewLocalRef)(JNIEnv*, jobject);
- jint (*EnsureLocalCapacity)(JNIEnv*, jint);
-
- jobject (*AllocObject)(JNIEnv*, jclass);
- jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...);
- jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);
- jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);
-
- jclass (*GetObjectClass)(JNIEnv*, jobject);
- jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass);
- jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
-
- jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
- jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
- jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
- jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
- jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
- jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
- jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
- jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...);
- jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);
- jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
- void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
- void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
- void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
-
- jobject (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass,
- jmethodID, ...);
- jobject (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass,
- jmethodID, va_list);
- jobject (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass,
- jmethodID, jvalue*);
- jboolean (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass,
- jmethodID, ...);
- jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass,
- jmethodID, va_list);
- jboolean (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass,
- jmethodID, jvalue*);
- jbyte (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass,
- jmethodID, ...);
- jbyte (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass,
- jmethodID, va_list);
- jbyte (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass,
- jmethodID, jvalue*);
- jchar (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass,
- jmethodID, ...);
- jchar (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass,
- jmethodID, va_list);
- jchar (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass,
- jmethodID, jvalue*);
- jshort (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass,
- jmethodID, ...);
- jshort (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass,
- jmethodID, va_list);
- jshort (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass,
- jmethodID, jvalue*);
- jint (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass,
- jmethodID, ...);
- jint (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass,
- jmethodID, va_list);
- jint (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass,
- jmethodID, jvalue*);
- jlong (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass,
- jmethodID, ...);
- jlong (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass,
- jmethodID, va_list);
- jlong (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass,
- jmethodID, jvalue*);
- jfloat (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass,
- jmethodID, ...);
- jfloat (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass,
- jmethodID, va_list);
- jfloat (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass,
- jmethodID, jvalue*);
- jdouble (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass,
- jmethodID, ...);
- jdouble (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass,
- jmethodID, va_list);
- jdouble (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass,
- jmethodID, jvalue*);
- void (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass,
- jmethodID, ...);
- void (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass,
- jmethodID, va_list);
- void (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass,
- jmethodID, jvalue*);
-
- jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);
-
- jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID);
- jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID);
- jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID);
- jchar (*GetCharField)(JNIEnv*, jobject, jfieldID);
- jshort (*GetShortField)(JNIEnv*, jobject, jfieldID);
- jint (*GetIntField)(JNIEnv*, jobject, jfieldID);
- jlong (*GetLongField)(JNIEnv*, jobject, jfieldID);
- jfloat (*GetFloatField)(JNIEnv*, jobject, jfieldID);
- jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID);
-
- void (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);
- void (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);
- void (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);
- void (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);
- void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);
- void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);
- void (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);
- void (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat);
- void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble);
-
- jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);
-
- jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);
- jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- jobject (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...);
- jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,
- va_list);
- jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID,
- jvalue*);
- jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...);
- jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...);
- jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- jshort (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...);
- jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- jshort (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...);
- jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...);
- jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- jfloat (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...);
- jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...);
- jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
- void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
- void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);
- void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
-
- jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*,
- const char*);
-
- jobject (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);
- jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);
- jbyte (*GetStaticByteField)(JNIEnv*, jclass, jfieldID);
- jchar (*GetStaticCharField)(JNIEnv*, jclass, jfieldID);
- jshort (*GetStaticShortField)(JNIEnv*, jclass, jfieldID);
- jint (*GetStaticIntField)(JNIEnv*, jclass, jfieldID);
- jlong (*GetStaticLongField)(JNIEnv*, jclass, jfieldID);
- jfloat (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID);
- jdouble (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID);
-
- void (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);
- void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);
- void (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);
- void (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);
- void (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);
- void (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);
- void (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);
- void (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat);
- void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble);
-
- jstring (*NewString)(JNIEnv*, const jchar*, jsize);
- jsize (*GetStringLength)(JNIEnv*, jstring);
- const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);
- void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);
- jstring (*NewStringUTF)(JNIEnv*, const char*);
- jsize (*GetStringUTFLength)(JNIEnv*, jstring);
- /* JNI spec says this returns const jbyte*, but that's inconsistent */
- const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);
- void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);
- jsize (*GetArrayLength)(JNIEnv*, jarray);
- jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject);
- jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize);
- void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject);
-
- jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
- jbyteArray (*NewByteArray)(JNIEnv*, jsize);
- jcharArray (*NewCharArray)(JNIEnv*, jsize);
- jshortArray (*NewShortArray)(JNIEnv*, jsize);
- jintArray (*NewIntArray)(JNIEnv*, jsize);
- jlongArray (*NewLongArray)(JNIEnv*, jsize);
- jfloatArray (*NewFloatArray)(JNIEnv*, jsize);
- jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize);
-
- jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);
- jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);
- jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);
- jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);
- jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
- jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);
- jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);
- jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);
-
- void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray,
- jboolean*, jint);
- void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray,
- jbyte*, jint);
- void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray,
- jchar*, jint);
- void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray,
- jshort*, jint);
- void (*ReleaseIntArrayElements)(JNIEnv*, jintArray,
- jint*, jint);
- void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray,
- jlong*, jint);
- void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray,
- jfloat*, jint);
- void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray,
- jdouble*, jint);
-
- void (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray,
- jsize, jsize, jboolean*);
- void (*GetByteArrayRegion)(JNIEnv*, jbyteArray,
- jsize, jsize, jbyte*);
- void (*GetCharArrayRegion)(JNIEnv*, jcharArray,
- jsize, jsize, jchar*);
- void (*GetShortArrayRegion)(JNIEnv*, jshortArray,
- jsize, jsize, jshort*);
- void (*GetIntArrayRegion)(JNIEnv*, jintArray,
- jsize, jsize, jint*);
- void (*GetLongArrayRegion)(JNIEnv*, jlongArray,
- jsize, jsize, jlong*);
- void (*GetFloatArrayRegion)(JNIEnv*, jfloatArray,
- jsize, jsize, jfloat*);
- void (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray,
- jsize, jsize, jdouble*);
-
- /* spec shows these without const; some jni.h do, some don't */
- void (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray,
- jsize, jsize, const jboolean*);
- void (*SetByteArrayRegion)(JNIEnv*, jbyteArray,
- jsize, jsize, const jbyte*);
- void (*SetCharArrayRegion)(JNIEnv*, jcharArray,
- jsize, jsize, const jchar*);
- void (*SetShortArrayRegion)(JNIEnv*, jshortArray,
- jsize, jsize, const jshort*);
- void (*SetIntArrayRegion)(JNIEnv*, jintArray,
- jsize, jsize, const jint*);
- void (*SetLongArrayRegion)(JNIEnv*, jlongArray,
- jsize, jsize, const jlong*);
- void (*SetFloatArrayRegion)(JNIEnv*, jfloatArray,
- jsize, jsize, const jfloat*);
- void (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray,
- jsize, jsize, const jdouble*);
-
- jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*,
- jint);
- jint (*UnregisterNatives)(JNIEnv*, jclass);
- jint (*MonitorEnter)(JNIEnv*, jobject);
- jint (*MonitorExit)(JNIEnv*, jobject);
- jint (*GetJavaVM)(JNIEnv*, JavaVM**);
-
- void (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*);
- void (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*);
-
- void* (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*);
- void (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint);
-
- const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*);
- void (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*);
-
- jweak (*NewWeakGlobalRef)(JNIEnv*, jobject);
- void (*DeleteWeakGlobalRef)(JNIEnv*, jweak);
-
- jboolean (*ExceptionCheck)(JNIEnv*);
-
- jobject (*NewDirectByteBuffer)(JNIEnv*, void*, jlong);
- void* (*GetDirectBufferAddress)(JNIEnv*, jobject);
- jlong (*GetDirectBufferCapacity)(JNIEnv*, jobject);
-
- /* added in JNI 1.6 */
- jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);
-};
-
-/*
- * C++ object wrapper.
- *
- * This is usually overlaid on a C struct whose first element is a
- * JNINativeInterface*. We rely somewhat on compiler behavior.
- */
-struct _JNIEnv {
- /* do not rename this; it does not seem to be entirely opaque */
- const struct JNINativeInterface* functions;
-
-#if defined(__cplusplus)
-
- jint GetVersion()
- { return functions->GetVersion(this); }
-
- jclass DefineClass(const char *name, jobject loader, const jbyte* buf,
- jsize bufLen)
- { return functions->DefineClass(this, name, loader, buf, bufLen); }
-
- jclass FindClass(const char* name)
- { return functions->FindClass(this, name); }
-
- jmethodID FromReflectedMethod(jobject method)
- { return functions->FromReflectedMethod(this, method); }
-
- jfieldID FromReflectedField(jobject field)
- { return functions->FromReflectedField(this, field); }
-
- jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic)
- { return functions->ToReflectedMethod(this, cls, methodID, isStatic); }
-
- jclass GetSuperclass(jclass clazz)
- { return functions->GetSuperclass(this, clazz); }
-
- jboolean IsAssignableFrom(jclass clazz1, jclass clazz2)
- { return functions->IsAssignableFrom(this, clazz1, clazz2); }
-
- jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic)
- { return functions->ToReflectedField(this, cls, fieldID, isStatic); }
-
- jint Throw(jthrowable obj)
- { return functions->Throw(this, obj); }
-
- jint ThrowNew(jclass clazz, const char* message)
- { return functions->ThrowNew(this, clazz, message); }
-
- jthrowable ExceptionOccurred()
- { return functions->ExceptionOccurred(this); }
-
- void ExceptionDescribe()
- { functions->ExceptionDescribe(this); }
-
- void ExceptionClear()
- { functions->ExceptionClear(this); }
-
- void FatalError(const char* msg)
- { functions->FatalError(this, msg); }
-
- jint PushLocalFrame(jint capacity)
- { return functions->PushLocalFrame(this, capacity); }
-
- jobject PopLocalFrame(jobject result)
- { return functions->PopLocalFrame(this, result); }
-
- jobject NewGlobalRef(jobject obj)
- { return functions->NewGlobalRef(this, obj); }
-
- void DeleteGlobalRef(jobject globalRef)
- { functions->DeleteGlobalRef(this, globalRef); }
-
- void DeleteLocalRef(jobject localRef)
- { functions->DeleteLocalRef(this, localRef); }
-
- jboolean IsSameObject(jobject ref1, jobject ref2)
- { return functions->IsSameObject(this, ref1, ref2); }
-
- jobject NewLocalRef(jobject ref)
- { return functions->NewLocalRef(this, ref); }
-
- jint EnsureLocalCapacity(jint capacity)
- { return functions->EnsureLocalCapacity(this, capacity); }
-
- jobject AllocObject(jclass clazz)
- { return functions->AllocObject(this, clazz); }
-
- jobject NewObject(jclass clazz, jmethodID methodID, ...)
- {
- va_list args;
- va_start(args, methodID);
- jobject result = functions->NewObjectV(this, clazz, methodID, args);
- va_end(args);
- return result;
- }
-
- jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args)
- { return functions->NewObjectV(this, clazz, methodID, args); }
-
- jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args)
- { return functions->NewObjectA(this, clazz, methodID, args); }
-
- jclass GetObjectClass(jobject obj)
- { return functions->GetObjectClass(this, obj); }
-
- jboolean IsInstanceOf(jobject obj, jclass clazz)
- { return functions->IsInstanceOf(this, obj, clazz); }
-
- jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
- { return functions->GetMethodID(this, clazz, name, sig); }
-
-#define CALL_TYPE_METHOD(_jtype, _jname) \
- _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...) \
- { \
- _jtype result; \
- va_list args; \
- va_start(args, methodID); \
- result = functions->Call##_jname##MethodV(this, obj, methodID, \
- args); \
- va_end(args); \
- return result; \
- }
-#define CALL_TYPE_METHODV(_jtype, _jname) \
- _jtype Call##_jname##MethodV(jobject obj, jmethodID methodID, \
- va_list args) \
- { return functions->Call##_jname##MethodV(this, obj, methodID, args); }
-#define CALL_TYPE_METHODA(_jtype, _jname) \
- _jtype Call##_jname##MethodA(jobject obj, jmethodID methodID, \
- jvalue* args) \
- { return functions->Call##_jname##MethodA(this, obj, methodID, args); }
-
-#define CALL_TYPE(_jtype, _jname) \
- CALL_TYPE_METHOD(_jtype, _jname) \
- CALL_TYPE_METHODV(_jtype, _jname) \
- CALL_TYPE_METHODA(_jtype, _jname)
-
- CALL_TYPE(jobject, Object)
- CALL_TYPE(jboolean, Boolean)
- CALL_TYPE(jbyte, Byte)
- CALL_TYPE(jchar, Char)
- CALL_TYPE(jshort, Short)
- CALL_TYPE(jint, Int)
- CALL_TYPE(jlong, Long)
- CALL_TYPE(jfloat, Float)
- CALL_TYPE(jdouble, Double)
-
- void CallVoidMethod(jobject obj, jmethodID methodID, ...)
- {
- va_list args;
- va_start(args, methodID);
- functions->CallVoidMethodV(this, obj, methodID, args);
- va_end(args);
- }
- void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args)
- { functions->CallVoidMethodV(this, obj, methodID, args); }
- void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args)
- { functions->CallVoidMethodA(this, obj, methodID, args); }
-
-#define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \
- _jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz, \
- jmethodID methodID, ...) \
- { \
- _jtype result; \
- va_list args; \
- va_start(args, methodID); \
- result = functions->CallNonvirtual##_jname##MethodV(this, obj, \
- clazz, methodID, args); \
- va_end(args); \
- return result; \
- }
-#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \
- _jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz, \
- jmethodID methodID, va_list args) \
- { return functions->CallNonvirtual##_jname##MethodV(this, obj, clazz, \
- methodID, args); }
-#define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) \
- _jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz, \
- jmethodID methodID, jvalue* args) \
- { return functions->CallNonvirtual##_jname##MethodA(this, obj, clazz, \
- methodID, args); }
-
-#define CALL_NONVIRT_TYPE(_jtype, _jname) \
- CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \
- CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \
- CALL_NONVIRT_TYPE_METHODA(_jtype, _jname)
-
- CALL_NONVIRT_TYPE(jobject, Object)
- CALL_NONVIRT_TYPE(jboolean, Boolean)
- CALL_NONVIRT_TYPE(jbyte, Byte)
- CALL_NONVIRT_TYPE(jchar, Char)
- CALL_NONVIRT_TYPE(jshort, Short)
- CALL_NONVIRT_TYPE(jint, Int)
- CALL_NONVIRT_TYPE(jlong, Long)
- CALL_NONVIRT_TYPE(jfloat, Float)
- CALL_NONVIRT_TYPE(jdouble, Double)
-
- void CallNonvirtualVoidMethod(jobject obj, jclass clazz,
- jmethodID methodID, ...)
- {
- va_list args;
- va_start(args, methodID);
- functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args);
- va_end(args);
- }
- void CallNonvirtualVoidMethodV(jobject obj, jclass clazz,
- jmethodID methodID, va_list args)
- { functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); }
- void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,
- jmethodID methodID, jvalue* args)
- { functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); }
-
- jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)
- { return functions->GetFieldID(this, clazz, name, sig); }
-
- jobject GetObjectField(jobject obj, jfieldID fieldID)
- { return functions->GetObjectField(this, obj, fieldID); }
- jboolean GetBooleanField(jobject obj, jfieldID fieldID)
- { return functions->GetBooleanField(this, obj, fieldID); }
- jbyte GetByteField(jobject obj, jfieldID fieldID)
- { return functions->GetByteField(this, obj, fieldID); }
- jchar GetCharField(jobject obj, jfieldID fieldID)
- { return functions->GetCharField(this, obj, fieldID); }
- jshort GetShortField(jobject obj, jfieldID fieldID)
- { return functions->GetShortField(this, obj, fieldID); }
- jint GetIntField(jobject obj, jfieldID fieldID)
- { return functions->GetIntField(this, obj, fieldID); }
- jlong GetLongField(jobject obj, jfieldID fieldID)
- { return functions->GetLongField(this, obj, fieldID); }
- jfloat GetFloatField(jobject obj, jfieldID fieldID)
- { return functions->GetFloatField(this, obj, fieldID); }
- jdouble GetDoubleField(jobject obj, jfieldID fieldID)
- { return functions->GetDoubleField(this, obj, fieldID); }
-
- void SetObjectField(jobject obj, jfieldID fieldID, jobject value)
- { functions->SetObjectField(this, obj, fieldID, value); }
- void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value)
- { functions->SetBooleanField(this, obj, fieldID, value); }
- void SetByteField(jobject obj, jfieldID fieldID, jbyte value)
- { functions->SetByteField(this, obj, fieldID, value); }
- void SetCharField(jobject obj, jfieldID fieldID, jchar value)
- { functions->SetCharField(this, obj, fieldID, value); }
- void SetShortField(jobject obj, jfieldID fieldID, jshort value)
- { functions->SetShortField(this, obj, fieldID, value); }
- void SetIntField(jobject obj, jfieldID fieldID, jint value)
- { functions->SetIntField(this, obj, fieldID, value); }
- void SetLongField(jobject obj, jfieldID fieldID, jlong value)
- { functions->SetLongField(this, obj, fieldID, value); }
- void SetFloatField(jobject obj, jfieldID fieldID, jfloat value)
- { functions->SetFloatField(this, obj, fieldID, value); }
- void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value)
- { functions->SetDoubleField(this, obj, fieldID, value); }
-
- jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig)
- { return functions->GetStaticMethodID(this, clazz, name, sig); }
-
-#define CALL_STATIC_TYPE_METHOD(_jtype, _jname) \
- _jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID, \
- ...) \
- { \
- _jtype result; \
- va_list args; \
- va_start(args, methodID); \
- result = functions->CallStatic##_jname##MethodV(this, clazz, \
- methodID, args); \
- va_end(args); \
- return result; \
- }
-#define CALL_STATIC_TYPE_METHODV(_jtype, _jname) \
- _jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID, \
- va_list args) \
- { return functions->CallStatic##_jname##MethodV(this, clazz, methodID, \
- args); }
-#define CALL_STATIC_TYPE_METHODA(_jtype, _jname) \
- _jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID, \
- jvalue* args) \
- { return functions->CallStatic##_jname##MethodA(this, clazz, methodID, \
- args); }
-
-#define CALL_STATIC_TYPE(_jtype, _jname) \
- CALL_STATIC_TYPE_METHOD(_jtype, _jname) \
- CALL_STATIC_TYPE_METHODV(_jtype, _jname) \
- CALL_STATIC_TYPE_METHODA(_jtype, _jname)
-
- CALL_STATIC_TYPE(jobject, Object)
- CALL_STATIC_TYPE(jboolean, Boolean)
- CALL_STATIC_TYPE(jbyte, Byte)
- CALL_STATIC_TYPE(jchar, Char)
- CALL_STATIC_TYPE(jshort, Short)
- CALL_STATIC_TYPE(jint, Int)
- CALL_STATIC_TYPE(jlong, Long)
- CALL_STATIC_TYPE(jfloat, Float)
- CALL_STATIC_TYPE(jdouble, Double)
-
- void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...)
- {
- va_list args;
- va_start(args, methodID);
- functions->CallStaticVoidMethodV(this, clazz, methodID, args);
- va_end(args);
- }
- void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args)
- { functions->CallStaticVoidMethodV(this, clazz, methodID, args); }
- void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args)
- { functions->CallStaticVoidMethodA(this, clazz, methodID, args); }
-
- jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)
- { return functions->GetStaticFieldID(this, clazz, name, sig); }
-
- jobject GetStaticObjectField(jclass clazz, jfieldID fieldID)
- { return functions->GetStaticObjectField(this, clazz, fieldID); }
- jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID)
- { return functions->GetStaticBooleanField(this, clazz, fieldID); }
- jbyte GetStaticByteField(jclass clazz, jfieldID fieldID)
- { return functions->GetStaticByteField(this, clazz, fieldID); }
- jchar GetStaticCharField(jclass clazz, jfieldID fieldID)
- { return functions->GetStaticCharField(this, clazz, fieldID); }
- jshort GetStaticShortField(jclass clazz, jfieldID fieldID)
- { return functions->GetStaticShortField(this, clazz, fieldID); }
- jint GetStaticIntField(jclass clazz, jfieldID fieldID)
- { return functions->GetStaticIntField(this, clazz, fieldID); }
- jlong GetStaticLongField(jclass clazz, jfieldID fieldID)
- { return functions->GetStaticLongField(this, clazz, fieldID); }
- jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID)
- { return functions->GetStaticFloatField(this, clazz, fieldID); }
- jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID)
- { return functions->GetStaticDoubleField(this, clazz, fieldID); }
-
- void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value)
- { functions->SetStaticObjectField(this, clazz, fieldID, value); }
- void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value)
- { functions->SetStaticBooleanField(this, clazz, fieldID, value); }
- void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value)
- { functions->SetStaticByteField(this, clazz, fieldID, value); }
- void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value)
- { functions->SetStaticCharField(this, clazz, fieldID, value); }
- void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value)
- { functions->SetStaticShortField(this, clazz, fieldID, value); }
- void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value)
- { functions->SetStaticIntField(this, clazz, fieldID, value); }
- void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value)
- { functions->SetStaticLongField(this, clazz, fieldID, value); }
- void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value)
- { functions->SetStaticFloatField(this, clazz, fieldID, value); }
- void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value)
- { functions->SetStaticDoubleField(this, clazz, fieldID, value); }
-
- jstring NewString(const jchar* unicodeChars, jsize len)
- { return functions->NewString(this, unicodeChars, len); }
-
- jsize GetStringLength(jstring string)
- { return functions->GetStringLength(this, string); }
-
- const jchar* GetStringChars(jstring string, jboolean* isCopy)
- { return functions->GetStringChars(this, string, isCopy); }
-
- void ReleaseStringChars(jstring string, const jchar* chars)
- { functions->ReleaseStringChars(this, string, chars); }
-
- jstring NewStringUTF(const char* bytes)
- { return functions->NewStringUTF(this, bytes); }
-
- jsize GetStringUTFLength(jstring string)
- { return functions->GetStringUTFLength(this, string); }
-
- const char* GetStringUTFChars(jstring string, jboolean* isCopy)
- { return functions->GetStringUTFChars(this, string, isCopy); }
-
- void ReleaseStringUTFChars(jstring string, const char* utf)
- { functions->ReleaseStringUTFChars(this, string, utf); }
-
- jsize GetArrayLength(jarray array)
- { return functions->GetArrayLength(this, array); }
-
- jobjectArray NewObjectArray(jsize length, jclass elementClass,
- jobject initialElement)
- { return functions->NewObjectArray(this, length, elementClass,
- initialElement); }
-
- jobject GetObjectArrayElement(jobjectArray array, jsize index)
- { return functions->GetObjectArrayElement(this, array, index); }
-
- void SetObjectArrayElement(jobjectArray array, jsize index, jobject value)
- { functions->SetObjectArrayElement(this, array, index, value); }
-
- jbooleanArray NewBooleanArray(jsize length)
- { return functions->NewBooleanArray(this, length); }
- jbyteArray NewByteArray(jsize length)
- { return functions->NewByteArray(this, length); }
- jcharArray NewCharArray(jsize length)
- { return functions->NewCharArray(this, length); }
- jshortArray NewShortArray(jsize length)
- { return functions->NewShortArray(this, length); }
- jintArray NewIntArray(jsize length)
- { return functions->NewIntArray(this, length); }
- jlongArray NewLongArray(jsize length)
- { return functions->NewLongArray(this, length); }
- jfloatArray NewFloatArray(jsize length)
- { return functions->NewFloatArray(this, length); }
- jdoubleArray NewDoubleArray(jsize length)
- { return functions->NewDoubleArray(this, length); }
-
- jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy)
- { return functions->GetBooleanArrayElements(this, array, isCopy); }
- jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy)
- { return functions->GetByteArrayElements(this, array, isCopy); }
- jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy)
- { return functions->GetCharArrayElements(this, array, isCopy); }
- jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy)
- { return functions->GetShortArrayElements(this, array, isCopy); }
- jint* GetIntArrayElements(jintArray array, jboolean* isCopy)
- { return functions->GetIntArrayElements(this, array, isCopy); }
- jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy)
- { return functions->GetLongArrayElements(this, array, isCopy); }
- jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy)
- { return functions->GetFloatArrayElements(this, array, isCopy); }
- jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy)
- { return functions->GetDoubleArrayElements(this, array, isCopy); }
-
- void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems,
- jint mode)
- { functions->ReleaseBooleanArrayElements(this, array, elems, mode); }
- void ReleaseByteArrayElements(jbyteArray array, jbyte* elems,
- jint mode)
- { functions->ReleaseByteArrayElements(this, array, elems, mode); }
- void ReleaseCharArrayElements(jcharArray array, jchar* elems,
- jint mode)
- { functions->ReleaseCharArrayElements(this, array, elems, mode); }
- void ReleaseShortArrayElements(jshortArray array, jshort* elems,
- jint mode)
- { functions->ReleaseShortArrayElements(this, array, elems, mode); }
- void ReleaseIntArrayElements(jintArray array, jint* elems,
- jint mode)
- { functions->ReleaseIntArrayElements(this, array, elems, mode); }
- void ReleaseLongArrayElements(jlongArray array, jlong* elems,
- jint mode)
- { functions->ReleaseLongArrayElements(this, array, elems, mode); }
- void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems,
- jint mode)
- { functions->ReleaseFloatArrayElements(this, array, elems, mode); }
- void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems,
- jint mode)
- { functions->ReleaseDoubleArrayElements(this, array, elems, mode); }
-
- void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
- jboolean* buf)
- { functions->GetBooleanArrayRegion(this, array, start, len, buf); }
- void GetByteArrayRegion(jbyteArray array, jsize start, jsize len,
- jbyte* buf)
- { functions->GetByteArrayRegion(this, array, start, len, buf); }
- void GetCharArrayRegion(jcharArray array, jsize start, jsize len,
- jchar* buf)
- { functions->GetCharArrayRegion(this, array, start, len, buf); }
- void GetShortArrayRegion(jshortArray array, jsize start, jsize len,
- jshort* buf)
- { functions->GetShortArrayRegion(this, array, start, len, buf); }
- void GetIntArrayRegion(jintArray array, jsize start, jsize len,
- jint* buf)
- { functions->GetIntArrayRegion(this, array, start, len, buf); }
- void GetLongArrayRegion(jlongArray array, jsize start, jsize len,
- jlong* buf)
- { functions->GetLongArrayRegion(this, array, start, len, buf); }
- void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
- jfloat* buf)
- { functions->GetFloatArrayRegion(this, array, start, len, buf); }
- void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
- jdouble* buf)
- { functions->GetDoubleArrayRegion(this, array, start, len, buf); }
-
- void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
- const jboolean* buf)
- { functions->SetBooleanArrayRegion(this, array, start, len, buf); }
- void SetByteArrayRegion(jbyteArray array, jsize start, jsize len,
- const jbyte* buf)
- { functions->SetByteArrayRegion(this, array, start, len, buf); }
- void SetCharArrayRegion(jcharArray array, jsize start, jsize len,
- const jchar* buf)
- { functions->SetCharArrayRegion(this, array, start, len, buf); }
- void SetShortArrayRegion(jshortArray array, jsize start, jsize len,
- const jshort* buf)
- { functions->SetShortArrayRegion(this, array, start, len, buf); }
- void SetIntArrayRegion(jintArray array, jsize start, jsize len,
- const jint* buf)
- { functions->SetIntArrayRegion(this, array, start, len, buf); }
- void SetLongArrayRegion(jlongArray array, jsize start, jsize len,
- const jlong* buf)
- { functions->SetLongArrayRegion(this, array, start, len, buf); }
- void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
- const jfloat* buf)
- { functions->SetFloatArrayRegion(this, array, start, len, buf); }
- void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
- const jdouble* buf)
- { functions->SetDoubleArrayRegion(this, array, start, len, buf); }
-
- jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,
- jint nMethods)
- { return functions->RegisterNatives(this, clazz, methods, nMethods); }
-
- jint UnregisterNatives(jclass clazz)
- { return functions->UnregisterNatives(this, clazz); }
-
- jint MonitorEnter(jobject obj)
- { return functions->MonitorEnter(this, obj); }
-
- jint MonitorExit(jobject obj)
- { return functions->MonitorExit(this, obj); }
-
- jint GetJavaVM(JavaVM** vm)
- { return functions->GetJavaVM(this, vm); }
-
- void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf)
- { functions->GetStringRegion(this, str, start, len, buf); }
-
- void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf)
- { return functions->GetStringUTFRegion(this, str, start, len, buf); }
-
- void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy)
- { return functions->GetPrimitiveArrayCritical(this, array, isCopy); }
-
- void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode)
- { functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); }
-
- const jchar* GetStringCritical(jstring string, jboolean* isCopy)
- { return functions->GetStringCritical(this, string, isCopy); }
-
- void ReleaseStringCritical(jstring string, const jchar* carray)
- { functions->ReleaseStringCritical(this, string, carray); }
-
- jweak NewWeakGlobalRef(jobject obj)
- { return functions->NewWeakGlobalRef(this, obj); }
-
- void DeleteWeakGlobalRef(jweak obj)
- { functions->DeleteWeakGlobalRef(this, obj); }
-
- jboolean ExceptionCheck()
- { return functions->ExceptionCheck(this); }
-
- jobject NewDirectByteBuffer(void* address, jlong capacity)
- { return functions->NewDirectByteBuffer(this, address, capacity); }
-
- void* GetDirectBufferAddress(jobject buf)
- { return functions->GetDirectBufferAddress(this, buf); }
-
- jlong GetDirectBufferCapacity(jobject buf)
- { return functions->GetDirectBufferCapacity(this, buf); }
-
- /* added in JNI 1.6 */
- jobjectRefType GetObjectRefType(jobject obj)
- { return functions->GetObjectRefType(this, obj); }
-#endif /*__cplusplus*/
-};
-
-
-/*
- * JNI invocation interface.
- */
-struct JNIInvokeInterface {
- void* reserved0;
- void* reserved1;
- void* reserved2;
-
- jint (*DestroyJavaVM)(JavaVM*);
- jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
- jint (*DetachCurrentThread)(JavaVM*);
- jint (*GetEnv)(JavaVM*, void**, jint);
- jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
-};
-
-/*
- * C++ version.
- */
-struct _JavaVM {
- const struct JNIInvokeInterface* functions;
-
-#if defined(__cplusplus)
- jint DestroyJavaVM()
- { return functions->DestroyJavaVM(this); }
- jint AttachCurrentThread(JNIEnv** p_env, void* thr_args)
- { return functions->AttachCurrentThread(this, p_env, thr_args); }
- jint DetachCurrentThread()
- { return functions->DetachCurrentThread(this); }
- jint GetEnv(void** env, jint version)
- { return functions->GetEnv(this, env, version); }
- jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args)
- { return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); }
-#endif /*__cplusplus*/
-};
-
-struct JavaVMAttachArgs {
- jint version; /* must be >= JNI_VERSION_1_2 */
- const char* name; /* NULL or name of thread as modified UTF-8 str */
- jobject group; /* global ref of a ThreadGroup object, or NULL */
-};
-typedef struct JavaVMAttachArgs JavaVMAttachArgs;
-
-/*
- * JNI 1.2+ initialization. (As of 1.6, the pre-1.2 structures are no
- * longer supported.)
- */
-typedef struct JavaVMOption {
- const char* optionString;
- void* extraInfo;
-} JavaVMOption;
-
-typedef struct JavaVMInitArgs {
- jint version; /* use JNI_VERSION_1_2 or later */
-
- jint nOptions;
- JavaVMOption* options;
- jboolean ignoreUnrecognized;
-} JavaVMInitArgs;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * VM initialization functions.
- *
- * Note these are the only symbols exported for JNI by the VM.
- */
-#if 0 /* In practice, these are not exported by the NDK so don't declare them */
-jint JNI_GetDefaultJavaVMInitArgs(void*);
-jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
-jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);
-#endif
-
-#define JNIIMPORT
-#define JNIEXPORT __attribute__ ((visibility ("default")))
-#define JNICALL __NDK_FPABI__
-
-/*
- * Prototypes for functions exported by loadable shared libs. These are
- * called by JNI, not provided by JNI.
- */
-JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved);
-JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-/*
- * Manifest constants.
- */
-#define JNI_FALSE 0
-#define JNI_TRUE 1
-
-#define JNI_VERSION_1_1 0x00010001
-#define JNI_VERSION_1_2 0x00010002
-#define JNI_VERSION_1_4 0x00010004
-#define JNI_VERSION_1_6 0x00010006
-
-#define JNI_OK (0) /* no error */
-#define JNI_ERR (-1) /* generic error */
-#define JNI_EDETACHED (-2) /* thread detached from the VM */
-#define JNI_EVERSION (-3) /* JNI version error */
-
-#define JNI_COMMIT 1 /* copy content, do not free buffer */
-#define JNI_ABORT 2 /* free buffer w/o copying back */
-
-#endif /* JNI_H_ */
diff --git a/examples/boxes/android/src/boxesp2p/main.go b/examples/boxes/android/src/boxesp2p/main.go
deleted file mode 100644
index 9654184..0000000
--- a/examples/boxes/android/src/boxesp2p/main.go
+++ /dev/null
@@ -1,424 +0,0 @@
-// TODO(kash): Rewrite this to use the new dir/object store api.
-// +build ignore
-
-// +build !darwin
-
-package main
-
-/*
-// NOTE: This example builds a shared-library that gets used in android. We use the goandroid
-// binary to build this and need the Android NDK to be installed. We create a local copy of jni.h
-// to get this compiling for normal builds (source: android-ndk-r9d-linux-x86_64.tar.bz2 downloaded
-// from https://developer.android.com/tools/sdk/ndk/index.html).
-#include "jni.h"
-#include <stdlib.h>
-
-// Use GetEnv to discover the thread's JNIEnv. JNIEnv cannot be shared
-// between threads. Once we are done we need to detach the thread.
-static JNIEnv* getJNIEnv(JavaVM *jvm) {
- JNIEnv *env;
- (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6);
- (*jvm)->AttachCurrentThread(jvm, &env, NULL);
- return env;
-}
-
-// Free the thread that has been attached to the JNIEnv.
-static void freeJNIEnv(JavaVM *jvm, JNIEnv* env) {
- (*jvm)->DetachCurrentThread(jvm);
-}
-
-// Conversions from JString to CString and vice-versa.
-static jstring CToJString(JNIEnv *env, const char* c) {
- return (*env)->NewStringUTF(env, c);
-}
-
-static const char* JToCString(JNIEnv *env, jstring jstr) {
- return (*env)->GetStringUTFChars(env, jstr, NULL);
-}
-
-// Get the Method ID for method "name" with given args.
-static jmethodID getMethodID(JNIEnv *env, jobject obj, const char* name, const char* args) {
- jclass jc = (*env)->GetObjectClass(env, obj);
- return (*env)->GetMethodID(env, jc, name, args);
-}
-
-// Calls the Java method in Android with the box description.
-static void callMethod(JNIEnv *env, jobject obj, jmethodID mid, jstring boxId, jfloat points[4]) {
- (*env)->CallVoidMethod(env, obj, mid, boxId, points[0], points[1], points[2], points[3]);
-}
-
-// Gets the global reference for a given object.
-static jobject newGlobalRef(JNIEnv *env, jobject obj) {
- return (*env)->NewGlobalRef(env, obj);
-}
-
-// Delete the global reference to a given object
-static void freeGlobalRef(JNIEnv *env, jobject obj) {
- (*env)->DeleteGlobalRef(env, obj);
-}
-*/
-import "C"
-
-import (
- "bytes"
- "fmt"
- "io"
- "net"
- "os"
- "runtime"
- "strings"
- "unsafe"
-
- "veyron/examples/boxes"
- inaming "veyron/runtimes/google/naming"
- vsync "veyron/runtimes/google/vsync"
- vsecurity "veyron/security"
- sstore "veyron.io/store/veyron/services/store/server"
-
- "veyron2"
- "veyron2/context"
- "veyron2/ipc"
- "veyron2/naming"
- "veyron2/rt"
- "veyron2/security"
- "veyron2/services/watch/types"
- "veyron.io/store/veyron2/storage"
- "veyron.io/store/veyron2/storage/vstore"
- "veyron2/vom"
-)
-
-type jniState struct {
- jVM *C.JavaVM
- jObj C.jobject
- jMID C.jmethodID
-}
-
-type boxesDispatcher struct {
- drawAuth, syncAuth security.Authorizer
- drawServer, syncServer ipc.Invoker
- storeDispatcher ipc.Dispatcher
-}
-
-type goState struct {
- runtime veyron2.Runtime
- ipc ipc.Server
- disp boxesDispatcher
- drawStream boxes.DrawInterfaceServiceDrawStream
- signalling boxes.BoxSignalling
- boxList chan boxes.Box
- myIPAddr string
- storeEndpoint string
-}
-
-var (
- gs goState
- nativeJava jniState
-)
-
-const (
- drawServicePort = ":8509"
- storeServicePort = ":8000"
- syncServicePort = ":8001"
- storePath = "/data/data/com.boxes.android.draganddraw/files/vsync"
- storeDatabase = "veyron_store.db"
- useStoreService = true
-)
-
-func (jni *jniState) registerAddBox(env *C.JNIEnv, obj C.jobject) {
- jni.jObj = C.newGlobalRef(env, obj)
- jni.jMID = C.getMethodID(env, nativeJava.jObj, C.CString("AddBox"), C.CString("(Ljava/lang/String;FFFF)V"))
-}
-
-func (jni *jniState) addBox(box *boxes.Box) {
- env := C.getJNIEnv(jni.jVM)
- defer C.freeJNIEnv(jni.jVM, env)
- // Convert box id/coordinates to java types
- var jPoints [4]C.jfloat
- for i := 0; i < 4; i++ {
- jPoints[i] = C.jfloat(box.Points[i])
- }
- jBoxId := C.CToJString(env, C.CString(box.BoxId))
- // Invoke the AddBox method in Java
- C.callMethod(env, jni.jObj, jni.jMID, jBoxId, &jPoints[0])
-}
-
-func (d *boxesDispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
- if strings.HasSuffix(suffix, "draw") {
- return d.drawServer, d.drawAuth, nil
- }
- if strings.HasSuffix(suffix, "sync") {
- return d.syncServer, d.syncAuth, nil
- }
- return d.storeDispatcher.Lookup(suffix, method)
-}
-
-func (gs *goState) SyncBoxes(context ipc.ServerContext) error {
- // Get the endpoint of the remote process
- endPt, err := inaming.NewEndpoint(context.RemoteEndpoint().String())
- if err != nil {
- return err
- }
- // Launch the sync service
- initSyncService(endPt.Addr().String())
- // Watch/Update the store for any box changes
- go gs.monitorStore()
- return nil
-}
-
-func (gs *goState) Draw(context ipc.ServerContext, stream boxes.DrawInterfaceServiceDrawStream) error {
- gs.drawStream = stream
- gs.streamBoxesLoop()
- return nil
-}
-
-func (gs *goState) sendBox(box boxes.Box) {
- gs.boxList <- box
-}
-
-func (gs *goState) streamBoxesLoop() {
- // Loop to receive boxes from remote peer
- go func() {
- rStream := gs.drawStream.RecvStream()
- for rStream.Advance() {
- box := rStream.Value()
- nativeJava.addBox(&box)
- }
- }()
- // Loop to send boxes to remote peer
- sender := gs.drawStream.SendStream()
- for {
- if err := sender.Send(<-gs.boxList); err != nil {
- break
- }
- }
-}
-
-func (gs *goState) monitorStore() {
- ctx := gs.runtime.NewContext()
-
- root := vstore.New().Bind(gs.storeEndpoint)
- if _, err := root.Put(ctx, ""); err != nil {
- panic(fmt.Errorf("Put for / failed:%v", err))
- }
-
- // Watch for any box updates from the store
- go func() {
- req := types.GlobRequest{Pattern: "*"}
- stream, err := root.WatchGlob(ctx, req)
- if err != nil {
- panic(fmt.Errorf("Can't watch store: %s: %s", gs.storeEndpoint, err))
- }
- rStream := stream.RecvStream()
- for rStream.Advance() {
- change := rStream.Value()
- if entry, ok := change.Value.(*storage.Entry); ok {
- if box, ok := entry.Value.(boxes.Box); ok && box.DeviceId != gs.myIPAddr {
- nativeJava.addBox(&box)
- }
- }
- }
-
- err = rStream.Err()
- if err == nil {
- err = io.EOF
- }
- panic(fmt.Errorf("Can't receive watch event: %s: %s", gs.storeEndpoint, err))
- }()
-
- // Send any box updates to the store
- for {
- box := <-gs.boxList
- if _, err := root.Bind(box.BoxId).Put(ctx, box); err != nil {
- panic(fmt.Errorf("Put for %s failed:%v", box.BoxId, err))
- }
- }
-}
-
-func (gs *goState) registerAsPeer(ctx context.T) {
- auth := vsecurity.NewACLAuthorizer(security.ACL{In: map[security.BlessingPattern]security.LabelSet{
- security.AllPrincipals: security.LabelSet(security.AdminLabel),
- }})
- gs.disp.drawAuth = auth
- gs.disp.drawServer = ipc.ReflectInvoker(boxes.NewServerDrawInterface(gs))
- endPt, err := gs.ipc.Listen("tcp", gs.myIPAddr+drawServicePort)
- if err != nil {
- panic(fmt.Errorf("Failed to Listen:%v", err))
- }
- if err := gs.ipc.Serve("", &gs.disp); err != nil {
- panic(fmt.Errorf("Failed Register:%v", err))
- }
- if err := gs.signalling.Add(ctx, endPt.String()); err != nil {
- panic(fmt.Errorf("Failed to Add endpoint to signalling server:%v", err))
- }
-}
-
-// wrapper is an object that modifies the signature of DrawInterfaceDrawCall
-// to match DrawInterfaceServiceDrawStream. This needs to happen because the
-// anonymous interface returned by SendStream in DrawInterfaceDrawCall has
-// an extra method (Close) that we need to remove from the function signataure.
-type wrapper struct {
- boxes.DrawInterfaceDrawCall
-}
-
-func (w *wrapper) SendStream() interface {
- Send(b boxes.Box) error
-} {
- return w.DrawInterfaceDrawCall.SendStream()
-}
-func (gs *goState) connectPeer(ctx context.T) {
- endpointStr, err := gs.signalling.Get(ctx)
- if err != nil {
- panic(fmt.Errorf("failed to Get peer endpoint from signalling server:%v", err))
- }
- drawInterface, err := boxes.BindDrawInterface(naming.JoinAddressName(endpointStr, "draw"))
- if err != nil {
- panic(fmt.Errorf("failed BindDrawInterface:%v", err))
- }
- if !useStoreService {
- val, err := drawInterface.Draw(ctx)
- if err != nil {
- panic(fmt.Errorf("failed to get handle to Draw stream:%v\n", err))
- }
- gs.drawStream = &wrapper{val}
- go gs.streamBoxesLoop()
- } else {
- // Initialize the store sync service that listens for updates from a peer
- endpoint, err := inaming.NewEndpoint(endpointStr)
- if err != nil {
- panic(fmt.Errorf("failed to parse endpoint:%v", err))
- }
- if err = drawInterface.SyncBoxes(ctx); err != nil {
- panic(fmt.Errorf("failed to setup remote sync service:%v", err))
- }
- initSyncService(endpoint.Addr().String())
- go gs.monitorStore()
- }
-}
-
-//export JNI_OnLoad
-func JNI_OnLoad(vm *C.JavaVM, reserved unsafe.Pointer) C.jint {
- nativeJava.jVM = vm
- return C.JNI_VERSION_1_6
-}
-
-//export Java_com_boxes_GoNative_registerAsPeer
-func Java_com_boxes_GoNative_registerAsPeer(env *C.JNIEnv) {
- ctx := gs.runtime.NewContext()
- gs.registerAsPeer(ctx)
-}
-
-//export Java_com_boxes_GoNative_connectPeer
-func Java_com_boxes_GoNative_connectPeer(env *C.JNIEnv) {
- ctx := gs.runtime.NewContext()
- gs.connectPeer(ctx)
-}
-
-//export Java_com_boxes_GoNative_sendDrawBox
-func Java_com_boxes_GoNative_sendDrawBox(env *C.JNIEnv, class C.jclass,
- boxId C.jstring, ox C.jfloat, oy C.jfloat, cx C.jfloat, cy C.jfloat) {
- gs.sendBox(boxes.Box{DeviceId: gs.myIPAddr, BoxId: C.GoString(C.JToCString(env, boxId)), Points: [4]float32{float32(ox), float32(oy), float32(cx), float32(cy)}})
-}
-
-//export Java_com_boxes_GoNative_registerAddBox
-func Java_com_boxes_GoNative_registerAddBox(env *C.JNIEnv, thisObj C.jobject, obj C.jobject) {
- nativeJava.registerAddBox(env, obj)
-}
-
-func initStoreService() {
- publicID := gs.runtime.Identity().PublicID()
- if len(publicID.Names()) == 0 {
- panic(fmt.Errorf("invalid PublicID:%v\n", publicID))
- }
-
- // Create a new store server
- storeDBName := storePath + "/" + storeDatabase
- store, err := sstore.New(sstore.ServerConfig{Admin: publicID, DBName: storeDBName})
- if err != nil {
- panic(fmt.Errorf("store.New() failed:%v", err))
- }
-
- // Create ACL Authorizer with read/write permissions for the identity
- acl, err := vsecurity.LoadACL(bytes.NewBufferString("{\"" + publicID.Names()[0] + "\":\"RW\"}"))
- if err != nil {
- panic(fmt.Errorf("LoadACL failed:%v", err))
- }
- auth := vsecurity.NewACLAuthorizer(acl)
- gs.disp.storeDispatcher = sstore.NewStoreDispatcher(store, auth)
-
- // Create an endpoint and start listening
- if _, err = gs.ipc.Listen("tcp", gs.myIPAddr+storeServicePort); err != nil {
- panic(fmt.Errorf("s.Listen() failed:%v", err))
- }
- // Register the services
- if err = gs.ipc.Serve("", &gs.disp); err != nil {
- panic(fmt.Errorf("s.Serve(store) failed:%v", err))
- }
- gs.storeEndpoint = "/" + gs.myIPAddr + storeServicePort
-}
-
-func initSyncService(peerEndpoint string) {
- peerSyncAddr := strings.Split(peerEndpoint, ":")[0]
- srv := vsync.NewServerSync(vsync.NewSyncd(peerSyncAddr+syncServicePort, peerSyncAddr /* peer deviceID */, gs.myIPAddr /* my deviceID */, storePath, gs.storeEndpoint, 0))
- gs.disp.syncAuth = nil
- gs.disp.syncServer = ipc.ReflectInvoker(srv)
- if _, err := gs.ipc.Listen("tcp", gs.myIPAddr+syncServicePort); err != nil {
- panic(fmt.Errorf("syncd:: error listening to service: err %v", err))
- }
- if err := gs.ipc.Serve("", &gs.disp); err != nil {
- panic(fmt.Errorf("syncd:: error serving service: err %v", err))
- }
-}
-
-func init() {
- // Register *storage.Entry for WatchGlob.
- // TODO(tilaks): storage.Entry is declared in vdl, vom should register the
- // pointer automatically.
- vom.Register(&storage.Entry{})
- runtime.GOMAXPROCS(runtime.NumCPU())
-}
-
-func main() {
- // Get an IP that can be published to the signal server
- ifaces, _ := net.InterfaceAddrs()
- for _, addr := range ifaces {
- if ipa, ok := addr.(*net.IPNet); ok {
- if ip4 := ipa.IP.To4(); ip4 != nil && ip4.String() != "127.0.0.1" {
- gs.myIPAddr = ip4.String()
- break
- }
- }
- }
- if len(gs.myIPAddr) <= 0 {
- panic(fmt.Errorf("Failed to get value IPAddr:%v", ifaces))
- }
-
- myIdentity := "_4EEGgFCAP-DNBoBQwEudmV5cm9uL3J1bnRpbWVzL2dvb2dsZS9zZWN1cml0eS5jaGFpblByaXZhdGVJRAD_hVEYAQIBRAEIUHVibGljSUQAAQQBBlNlY3JldAABM3ZleXJvbi9ydW50aW1lcy9nb29nbGUvc2VjdXJpdHkvd2lyZS5DaGFpblByaXZhdGVJRAD_hwQaAUUA_4lJGAEBAUYBDENlcnRpZmljYXRlcwABMnZleXJvbi9ydW50aW1lcy9nb29nbGUvc2VjdXJpdHkvd2lyZS5DaGFpblB1YmxpY0lEAP-LBBIBRwD_jWcYAQQBAwEETmFtZQABSAEJUHVibGljS2V5AAFJAQdDYXZlYXRzAAFKAQlTaWduYXR1cmUAATB2ZXlyb24vcnVudGltZXMvZ29vZ2xlL3NlY3VyaXR5L3dpcmUuQ2VydGlmaWNhdGUA_49FGAECAUsBBUN1cnZlAAEEAQJYWQABLnZleXJvbi9ydW50aW1lcy9nb29nbGUvc2VjdXJpdHkvd2lyZS5QdWJsaWNLZXkA_5UzEAEyAS12ZXlyb24vcnVudGltZXMvZ29vZ2xlL3NlY3VyaXR5L3dpcmUua2V5Q3VydmUA_5EEEgFMAP-XRxgBAgFNAQdTZXJ2aWNlAAEEAQVCeXRlcwABK3ZleXJvbi9ydW50aW1lcy9nb29nbGUvc2VjdXJpdHkvd2lyZS5DYXZlYXQA_5knEAEDASF2ZXlyb24yL3NlY3VyaXR5LlByaW5jaXBhbFBhdHRlcm4A_5NAGAECAQQBAVIAAQQBAVMAAS52ZXlyb24vcnVudGltZXMvZ29vZ2xlL3NlY3VyaXR5L3dpcmUuU2lnbmF0dXJlAP-C_8ABAwEFAQEBCGdhdXRoYW10AQJBBL1M858IVO3sxJTYFxv1EiDVLFG6WdH-l4OpOHQXlZn5MO8LXNdnRhJ_r_Zwe92VHpbemsPNek_SJOfsSmsVRA8AAgEgm5eZNI1lUqwPCqlQOgesp-7zx0zLxvJe9IcwRbnMycoBINYA7GSPqFxDkbWYScL3Kj0k4AZK-e9sF01a7RAjcGMRAAAAASBldL9q-34I_W5yrapTmqaItm66RGNGtiUrFTlfh8VaNwA="
-
- // Load identity that has been generated.
- privateID, err := vsecurity.LoadIdentity(strings.NewReader(myIdentity))
- if err != nil {
- panic(fmt.Errorf("Failed to load identity:%v\n", err))
- }
-
- // Remove any remnant files from the store directory
- if err = os.RemoveAll(storePath); err != nil {
- panic(fmt.Errorf("Failed to remove remnant store files:%v\n", err))
- }
-
- gs.boxList = make(chan boxes.Box, 256)
-
- // Initialize veyron runtime and bind to the signalling server used to rendezvous with
- // another peer device. TODO(gauthamt): Switch to using the nameserver for signalling.
- gs.runtime = rt.Init(veyron2.RuntimeID(privateID))
- if gs.signalling, err = boxes.BindBoxSignalling(naming.JoinAddressName("@2@tcp@162.222.181.93:8509@08a93d90836cd94d4dc1acbe40b9048d@1@1@@", "signalling")); err != nil {
- panic(fmt.Errorf("failed to bind to signalling server:%v\n", err))
- }
-
- // Create a new server instance
- if gs.ipc, err = gs.runtime.NewServer(); err != nil {
- panic(fmt.Errorf("r.NewServer() failed:%v", err))
- }
-
- // Initialize an instance of the store service for this device
- initStoreService()
-}
diff --git a/examples/boxes/android/src/com/boxes/AndroidManifest.xml b/examples/boxes/android/src/com/boxes/AndroidManifest.xml
deleted file mode 100644
index 444165a..0000000
--- a/examples/boxes/android/src/com/boxes/AndroidManifest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.bignerdranch.android.draganddraw"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-sdk
- android:minSdkVersion="8"
- android:targetSdkVersion="18" />
- <!-- Permission required to use the TCP transport -->
- <uses-permission android:name="android.permission.INTERNET"/>
- <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
- <!-- Permission required to use the Bluetooth transport -->
- <uses-permission android:name="android.permission.BLUETOOTH"/>
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <activity
- android:name="com.boxes.DragAndDrawActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
diff --git a/examples/boxes/android/src/com/boxes/Box.java b/examples/boxes/android/src/com/boxes/Box.java
deleted file mode 100644
index 2238fbd..0000000
--- a/examples/boxes/android/src/com/boxes/Box.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.boxes;
-
-import java.util.Random;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import android.graphics.PointF;
-import android.os.Bundle;
-
-/*
- * Box represents a square on a canvas that has been drawn. The
- * ACTION_DOWN event becomes the origin of the box and the final
- * position is when the ACTION_UP event is detected.
- */
-public class Box {
- // Start/End positions of the square box
- private PointF mOrigin;
- private PointF mCurrent;
-
- // Unique name of this box
- private String mBoxId;
-
- // UniqueID that identifies which device a box came from
- // when there are multiple peers.
- private static AtomicInteger idCounter = new AtomicInteger(0);
- private static String uniqueID;
- static {
- uniqueID = "box:" + Math.abs(new Random().nextInt());
- }
-
- // Initialize a new box with a given start co-ordinate.
- public Box(PointF origin) {
- mOrigin = mCurrent = origin;
- mBoxId = uniqueID + "" + idCounter.incrementAndGet();
- }
-
- // Initialize a new box with given attributes
- public Box(String boxId, PointF origin, PointF current) {
- mBoxId = boxId;
- mOrigin = origin;
- mCurrent = current;
- }
-
- // Initialize a box from a packaged bundle.
- public Box(Bundle b) {
- final float[] points = b.getFloatArray("mPoints");
- setOrigin(new PointF(points[0], points[1]));
- setCurrent(new PointF(points[2], points[3]));
- setBoxId(b.getString("mBoxId"));
- }
-
- // Package a box into a bundle that can be stored.
- public Bundle toBundle() {
- final float[] points = { mOrigin.x, mOrigin.y, mCurrent.x, mCurrent.y };
- final Bundle bundle = new Bundle();
- bundle.putFloatArray("mPoints", points);
- bundle.putString("mBoxId", mBoxId);
- return bundle;
- }
-
- public String getBoxId() {
- return mBoxId;
- }
-
- public void setBoxId(String boxId) {
- mBoxId = boxId;
- }
-
- public void setCurrent(PointF current) {
- mCurrent = current;
- }
-
- public PointF getCurrent() {
- return mCurrent;
- }
-
- public void setOrigin(PointF origin) {
- mOrigin = origin;
- }
-
- public PointF getOrigin() {
- return mOrigin;
- }
-}
diff --git a/examples/boxes/android/src/com/boxes/BoxDrawingController.java b/examples/boxes/android/src/com/boxes/BoxDrawingController.java
deleted file mode 100644
index f7d0556..0000000
--- a/examples/boxes/android/src/com/boxes/BoxDrawingController.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package com.boxes;
-
-import java.util.ArrayList;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PointF;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Parcelable;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-/*
- * BoxDrawingController is the controller for our View. It handles touch events
- * and updates the model as needed. If peer sync has been activated the controller
- * is also responsible for communicating the changes to the remote device through
- * GoRemoteService.
- */
-public class BoxDrawingController extends View {
- public static final String PARCELKEY = "BoxViewParcel";
-
- private Box mCurrentBox;
- private ArrayList<Box> mBoxes = new ArrayList<Box>();
- private GoRemoteService mGoRemoteService;
-
- // Color codes for the box, box boundary-line and the background canvas
- private Paint mBoxPaint;
- private Paint mLinePaint;
- private Paint mBackgroundPaint;
-
- // This method is registered with the go-shared library through JNI. When the
- // go shared-library receives an update from a remote-device it notifies the
- // application via this callback.
- public void AddBox(String boxId, float oX, float oY, float cX, float cY) {
- final Box box = new Box(boxId, new PointF(oX, oY), new PointF(cX, cY));
- // The View can only be changed in the UI thread.
- post(new Runnable() {
- @Override
- public void run() {
- AddRemoteBox(box);
- }
- });
- }
-
- public boolean onTouchEvent(MotionEvent event) {
- final PointF current = new PointF(event.getX(), event.getY());
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mCurrentBox = new Box(current);
- mBoxes.add(mCurrentBox);
- break;
- case MotionEvent.ACTION_MOVE:
- if (mCurrentBox != null) {
- mCurrentBox.setCurrent(current);
- // Send the box over to any peer device.
- RemoteDraw(mCurrentBox);
- // View has changed, re-draw it.
- invalidate();
- }
- break;
- case MotionEvent.ACTION_UP:
- mCurrentBox = null;
- break;
- }
- return true;
- }
-
- public BoxDrawingController(Context context) {
- this(context, null);
- }
-
- public BoxDrawingController(Context context, AttributeSet attrs) {
- super(context, attrs);
- this.setSaveEnabled(true);
-
- mBoxPaint = new Paint();
- mBoxPaint.setColor(Color.GREEN);
-
- mLinePaint = new Paint();
- mLinePaint.setStrokeWidth(4f);
- mLinePaint.setColor(Color.BLACK);
-
- mBackgroundPaint = new Paint();
- mBackgroundPaint.setColor(0xfff8efe0);
-
- // Register the AddBox method with the shared-libary so that it knows
- // which callback to use.
- GoNative.registerAddBox(this);
- }
-
- // SetGoRemoteService sets the service that uses an underlying
- // go shared-library to talk to other devices with Veyron.
- void SetGoRemoteService(GoRemoteService goService) {
- mGoRemoteService = goService;
- }
-
- // We got a remote box from another peer device. Add it to my current
- // state and refresh the view.
- void AddRemoteBox(Box newBox) {
- for (Box box : mBoxes) {
- if (newBox.getBoxId().equals(box.getBoxId())) {
- // The box already exists. We just need to update its
- // coordinates.
- box.setOrigin(newBox.getOrigin());
- box.setCurrent(newBox.getCurrent());
- invalidate();
- return;
- }
- }
- mBoxes.add(newBox);
- // refresh the view.
- invalidate();
- }
-
- // Need to send over my entire current state to the
- // remote device.
- public void RemoteSync() {
- if (mGoRemoteService != null) {
- for (Box box : mBoxes) {
- mGoRemoteService.RemoteDraw(box);
- }
- }
- }
-
- // Send box information over to any peer device.
- public void RemoteDraw(Box box) {
- if (mGoRemoteService != null) {
- mGoRemoteService.RemoteDraw(box);
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.drawPaint(mBackgroundPaint);
- for (Box box : mBoxes) {
- float left = Math.min(box.getOrigin().x, box.getCurrent().x);
- float right = Math.max(box.getOrigin().x, box.getCurrent().x);
- float top = Math.min(box.getOrigin().y, box.getCurrent().y);
- float bottom = Math.max(box.getOrigin().y, box.getCurrent().y);
- canvas.drawRect(left, top, right, bottom, mBoxPaint);
- canvas.drawLine(box.getOrigin().x, box.getOrigin().y, box.getCurrent().x, box.getCurrent().y, mLinePaint);
- canvas.drawLine(box.getCurrent().x, box.getOrigin().y, box.getOrigin().x, box.getCurrent().y, mLinePaint);
- }
- }
-
- @Override
- public Parcelable onSaveInstanceState() {
- Parcelable p = super.onSaveInstanceState();
- Bundle bundle = new Bundle();
- for (Box box : mBoxes) {
- bundle.putBundle(box.getBoxId(), box.toBundle());
- }
- bundle.putParcelable(PARCELKEY, p);
- return (Parcelable)bundle;
- }
-
- @Override
- public void onRestoreInstanceState(Parcelable state) {
- Bundle bundle = (Bundle)state;
- super.onRestoreInstanceState(bundle.getParcelable(PARCELKEY));
- for (String s : bundle.keySet()) {
- if (s == PARCELKEY) continue;
- mBoxes.add(new Box(bundle.getBundle(s)));
- }
- }
-}
diff --git a/examples/boxes/android/src/com/boxes/DragAndDrawActivity.java b/examples/boxes/android/src/com/boxes/DragAndDrawActivity.java
deleted file mode 100644
index d8c04ed..0000000
--- a/examples/boxes/android/src/com/boxes/DragAndDrawActivity.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.boxes;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-
-public class DragAndDrawActivity extends SingleFragmentActivity {
-
- private class DragAndDrawFragment extends Fragment {
- private GoRemoteService mGoRemoteService;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- mGoRemoteService = new GoRemoteService();
- mGoRemoteService.start();
- mGoRemoteService.getLooper();
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_drag_and_draw, parent, false);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- inflater.inflate(R.menu.fragment_dragdraw, menu);
- }
-
- @SuppressLint("NewApi")
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- final BoxDrawingController bdc =
- (BoxDrawingController)getActivity().findViewById(R.id.boxDrawingView);
- bdc.SetGoRemoteService(mGoRemoteService);
-
- switch (item.getItemId()) {
- case R.id.menu_start:
- // Register this device with a signalling server so that other
- // peers can find it.
- GoNative.registerAsPeer();
- item.setEnabled(false);
- return true;
- case R.id.menu_join:
- // Join with any peer that has already registered itself with
- // the signalling server.
- GoNative.connectPeer();
- // Sync my state with the remote peer.
- bdc.RemoteSync();
- item.setEnabled(false);
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
- }
-
- @Override
- public Fragment createFragment() {
- return new DragAndDrawFragment();
- }
-}
diff --git a/examples/boxes/android/src/com/boxes/GoNative.java b/examples/boxes/android/src/com/boxes/GoNative.java
deleted file mode 100644
index edcec6e..0000000
--- a/examples/boxes/android/src/com/boxes/GoNative.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.boxes;
-
-import android.util.Log;
-
-public class GoNative {
- static native void registerAsPeer();
- static native void connectPeer();
- static native void sendDrawBox(String boxId, float oX, float oY, float cX, float cY);
- static native void registerAddBox(BoxDrawingController bdc);
-
- static {
- System.loadLibrary("boxesp2p");
- }
-}
diff --git a/examples/boxes/android/src/com/boxes/GoRemoteService.java b/examples/boxes/android/src/com/boxes/GoRemoteService.java
deleted file mode 100644
index 782daf6..0000000
--- a/examples/boxes/android/src/com/boxes/GoRemoteService.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.boxes;
-
-import android.graphics.PointF;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Message;
-
-public class GoRemoteService extends HandlerThread {
- private static final int MESSAGE_DRAW = 0;
- private final Handler mRequestHandler;
-
- // Handle the send to the peer device in a separate thread.
- public GoRemoteService() {
- super("GoRemoteService");
- mRequestHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == MESSAGE_DRAW) {
- final Box box = new Box(msg.getData());
- final PointF origin = box.getOrigin();
- final PointF current = box.getCurrent();
- GoNative.sendDrawBox(box.getBoxId(), origin.x, origin.y, current.x, current.y);
- }
- }
- };
- }
-
- // Send a box to a peer device via the go native shared library.
- public void RemoteDraw(Box box) {
- final Message msg = mRequestHandler.obtainMessage(MESSAGE_DRAW);
- msg.setData(box.toBundle());
- msg.sendToTarget();
- }
-}
diff --git a/examples/boxes/android/src/com/boxes/SingleFragmentActivity.java b/examples/boxes/android/src/com/boxes/SingleFragmentActivity.java
deleted file mode 100644
index 3788895..0000000
--- a/examples/boxes/android/src/com/boxes/SingleFragmentActivity.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.boxes;
-
-import com.boxes.R;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
-
-public abstract class SingleFragmentActivity extends FragmentActivity {
- protected abstract Fragment createFragment();
-
- protected int getLayoutResId() {
- return R.layout.activity_fragment;
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(getLayoutResId());
- final FragmentManager fm = getSupportFragmentManager();
- Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
- if (fragment == null) {
- fragment = createFragment();
- fm.beginTransaction().add(R.id.fragmentContainer, fragment).commit();
- }
- }
-}
diff --git a/examples/boxes/boxes.vdl b/examples/boxes/boxes.vdl
deleted file mode 100644
index 1736cd4..0000000
--- a/examples/boxes/boxes.vdl
+++ /dev/null
@@ -1,31 +0,0 @@
-// Boxes is an android app that uses veyron to share views
-// between peer devices.
-package boxes
-
-// BoxSignalling allows peers to rendezvous with each other
-type BoxSignalling interface {
- // Add endpoint information to the signalling server.
- Add(Endpoint string) (Err error)
- // Get endpoint information about a peer.
- Get() (Endpoint string, Err error)
-}
-
-// Box describes the name and co-ordinates of a given box that
-// is displayed in the View of a peer device.
-type Box struct {
- // DeviceID that generated the box
- DeviceId string
- // BoxId is a unique name for a box
- BoxId string
- // Points are the co-ordinates of a given box
- Points [4]float32
-}
-
-// DrawInterface enables adding a box on another peer
-type DrawInterface interface {
- // Draw is used to send/receive a stream of boxes to another peer
- Draw() stream<Box, Box> (Err error)
- // SyncBoxes is used to setup a sync service over store to send/receive
- // boxes to another peer
- SyncBoxes() (Err error)
-}
diff --git a/examples/boxes/boxes.vdl.go b/examples/boxes/boxes.vdl.go
deleted file mode 100644
index 12ee354..0000000
--- a/examples/boxes/boxes.vdl.go
+++ /dev/null
@@ -1,660 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: boxes.vdl
-
-// Boxes is an android app that uses veyron to share views
-// between peer devices.
-package boxes
-
-import (
- // The non-user imports are prefixed with "_gen_" to prevent collisions.
- _gen_io "io"
- _gen_veyron2 "veyron2"
- _gen_context "veyron2/context"
- _gen_ipc "veyron2/ipc"
- _gen_naming "veyron2/naming"
- _gen_vdlutil "veyron2/vdl/vdlutil"
- _gen_wiretype "veyron2/wiretype"
-)
-
-// Box describes the name and co-ordinates of a given box that
-// is displayed in the View of a peer device.
-type Box struct {
- // DeviceID that generated the box
- DeviceId string
- // BoxId is a unique name for a box
- BoxId string
- // Points are the co-ordinates of a given box
- Points [4]float32
-}
-
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
-const _ = _gen_wiretype.TypeIDInvalid
-
-// BoxSignalling allows peers to rendezvous with each other
-// BoxSignalling is the interface the client binds and uses.
-// BoxSignalling_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type BoxSignalling_ExcludingUniversal interface {
- // Add endpoint information to the signalling server.
- Add(ctx _gen_context.T, Endpoint string, opts ..._gen_ipc.CallOpt) (err error)
- // Get endpoint information about a peer.
- Get(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply string, err error)
-}
-type BoxSignalling interface {
- _gen_ipc.UniversalServiceMethods
- BoxSignalling_ExcludingUniversal
-}
-
-// BoxSignallingService is the interface the server implements.
-type BoxSignallingService interface {
-
- // Add endpoint information to the signalling server.
- Add(context _gen_ipc.ServerContext, Endpoint string) (err error)
- // Get endpoint information about a peer.
- Get(context _gen_ipc.ServerContext) (reply string, err error)
-}
-
-// BindBoxSignalling returns the client stub implementing the BoxSignalling
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindBoxSignalling(name string, opts ..._gen_ipc.BindOpt) (BoxSignalling, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubBoxSignalling{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerBoxSignalling creates a new server stub.
-//
-// It takes a regular server implementing the BoxSignallingService
-// interface, and returns a new server stub.
-func NewServerBoxSignalling(server BoxSignallingService) interface{} {
- return &ServerStubBoxSignalling{
- service: server,
- }
-}
-
-// clientStubBoxSignalling implements BoxSignalling.
-type clientStubBoxSignalling struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubBoxSignalling) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubBoxSignalling) Add(ctx _gen_context.T, Endpoint string, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Add", []interface{}{Endpoint}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBoxSignalling) Get(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Get", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBoxSignalling) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBoxSignalling) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubBoxSignalling) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubBoxSignalling wraps a server that implements
-// BoxSignallingService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubBoxSignalling struct {
- service BoxSignallingService
-}
-
-func (__gen_s *ServerStubBoxSignalling) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Add":
- return []interface{}{}, nil
- case "Get":
- return []interface{}{}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubBoxSignalling) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Add"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "Endpoint", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "Err", Type: 65},
- },
- }
- result.Methods["Get"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "Endpoint", Type: 3},
- {Name: "Err", Type: 65},
- },
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
-
- return result, nil
-}
-
-func (__gen_s *ServerStubBoxSignalling) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubBoxSignalling) Add(call _gen_ipc.ServerCall, Endpoint string) (err error) {
- err = __gen_s.service.Add(call, Endpoint)
- return
-}
-
-func (__gen_s *ServerStubBoxSignalling) Get(call _gen_ipc.ServerCall) (reply string, err error) {
- reply, err = __gen_s.service.Get(call)
- return
-}
-
-// DrawInterface enables adding a box on another peer
-// DrawInterface is the interface the client binds and uses.
-// DrawInterface_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type DrawInterface_ExcludingUniversal interface {
- // Draw is used to send/receive a stream of boxes to another peer
- Draw(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply DrawInterfaceDrawCall, err error)
- // SyncBoxes is used to setup a sync service over store to send/receive
- // boxes to another peer
- SyncBoxes(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error)
-}
-type DrawInterface interface {
- _gen_ipc.UniversalServiceMethods
- DrawInterface_ExcludingUniversal
-}
-
-// DrawInterfaceService is the interface the server implements.
-type DrawInterfaceService interface {
-
- // Draw is used to send/receive a stream of boxes to another peer
- Draw(context _gen_ipc.ServerContext, stream DrawInterfaceServiceDrawStream) (err error)
- // SyncBoxes is used to setup a sync service over store to send/receive
- // boxes to another peer
- SyncBoxes(context _gen_ipc.ServerContext) (err error)
-}
-
-// DrawInterfaceDrawCall is the interface for call object of the method
-// Draw in the service interface DrawInterface.
-type DrawInterfaceDrawCall interface {
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() Box
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-
- // SendStream returns the send portion of the stream
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no
- // buffer space available. Calls to Send after having called Close
- // or Cancel will fail. Any blocked Send calls will be unblocked upon
- // calling Cancel.
- Send(item Box) error
-
- // Close indicates to the server that no more items will be sent;
- // server Recv calls will receive io.EOF after all sent items. This is
- // an optional call - it's used by streaming clients that need the
- // server to receive the io.EOF terminator before the client calls
- // Finish (for example, if the client needs to continue receiving items
- // from the server after having finished sending).
- // Calls to Close after having called Cancel will fail.
- // Like Send, Close blocks when there's no buffer space available.
- Close() error
- }
-
- // Finish performs the equivalent of SendStream().Close, then blocks until the server
- // is done, and returns the positional return values for call.
- // If Cancel has been called, Finish will return immediately; the output of
- // Finish could either be an error signalling cancelation, or the correct
- // positional return values from the server depending on the timing of the
- // call.
- //
- // Calling Finish is mandatory for releasing stream resources, unless Cancel
- // has been called or any of the other methods return an error.
- // Finish should be called at most once.
- Finish() (err error)
-
- // Cancel cancels the RPC, notifying the server to stop processing. It
- // is safe to call Cancel concurrently with any of the other stream methods.
- // Calling Cancel after Finish has returned is a no-op.
- Cancel()
-}
-
-type implDrawInterfaceDrawStreamSender struct {
- clientCall _gen_ipc.Call
-}
-
-func (c *implDrawInterfaceDrawStreamSender) Send(item Box) error {
- return c.clientCall.Send(item)
-}
-
-func (c *implDrawInterfaceDrawStreamSender) Close() error {
- return c.clientCall.CloseSend()
-}
-
-type implDrawInterfaceDrawStreamIterator struct {
- clientCall _gen_ipc.Call
- val Box
- err error
-}
-
-func (c *implDrawInterfaceDrawStreamIterator) Advance() bool {
- c.val = Box{}
- c.err = c.clientCall.Recv(&c.val)
- return c.err == nil
-}
-
-func (c *implDrawInterfaceDrawStreamIterator) Value() Box {
- return c.val
-}
-
-func (c *implDrawInterfaceDrawStreamIterator) Err() error {
- if c.err == _gen_io.EOF {
- return nil
- }
- return c.err
-}
-
-// Implementation of the DrawInterfaceDrawCall interface that is not exported.
-type implDrawInterfaceDrawCall struct {
- clientCall _gen_ipc.Call
- writeStream implDrawInterfaceDrawStreamSender
- readStream implDrawInterfaceDrawStreamIterator
-}
-
-func (c *implDrawInterfaceDrawCall) SendStream() interface {
- Send(item Box) error
- Close() error
-} {
- return &c.writeStream
-}
-
-func (c *implDrawInterfaceDrawCall) RecvStream() interface {
- Advance() bool
- Value() Box
- Err() error
-} {
- return &c.readStream
-}
-
-func (c *implDrawInterfaceDrawCall) Finish() (err error) {
- if ierr := c.clientCall.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (c *implDrawInterfaceDrawCall) Cancel() {
- c.clientCall.Cancel()
-}
-
-type implDrawInterfaceServiceDrawStreamSender struct {
- serverCall _gen_ipc.ServerCall
-}
-
-func (s *implDrawInterfaceServiceDrawStreamSender) Send(item Box) error {
- return s.serverCall.Send(item)
-}
-
-type implDrawInterfaceServiceDrawStreamIterator struct {
- serverCall _gen_ipc.ServerCall
- val Box
- err error
-}
-
-func (s *implDrawInterfaceServiceDrawStreamIterator) Advance() bool {
- s.val = Box{}
- s.err = s.serverCall.Recv(&s.val)
- return s.err == nil
-}
-
-func (s *implDrawInterfaceServiceDrawStreamIterator) Value() Box {
- return s.val
-}
-
-func (s *implDrawInterfaceServiceDrawStreamIterator) Err() error {
- if s.err == _gen_io.EOF {
- return nil
- }
- return s.err
-}
-
-// DrawInterfaceServiceDrawStream is the interface for streaming responses of the method
-// Draw in the service interface DrawInterface.
-type DrawInterfaceServiceDrawStream interface {
- // SendStream returns the send portion of the stream.
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item Box) error
- }
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() Box
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-}
-
-// Implementation of the DrawInterfaceServiceDrawStream interface that is not exported.
-type implDrawInterfaceServiceDrawStream struct {
- writer implDrawInterfaceServiceDrawStreamSender
- reader implDrawInterfaceServiceDrawStreamIterator
-}
-
-func (s *implDrawInterfaceServiceDrawStream) SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item Box) error
-} {
- return &s.writer
-}
-
-func (s *implDrawInterfaceServiceDrawStream) RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. The client must call Cancel if it does
- // not iterate through all elements (i.e. until Advance
- // returns false). Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() Box
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
-} {
- return &s.reader
-}
-
-// BindDrawInterface returns the client stub implementing the DrawInterface
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindDrawInterface(name string, opts ..._gen_ipc.BindOpt) (DrawInterface, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubDrawInterface{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerDrawInterface creates a new server stub.
-//
-// It takes a regular server implementing the DrawInterfaceService
-// interface, and returns a new server stub.
-func NewServerDrawInterface(server DrawInterfaceService) interface{} {
- return &ServerStubDrawInterface{
- service: server,
- }
-}
-
-// clientStubDrawInterface implements DrawInterface.
-type clientStubDrawInterface struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubDrawInterface) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubDrawInterface) Draw(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply DrawInterfaceDrawCall, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Draw", nil, opts...); err != nil {
- return
- }
- reply = &implDrawInterfaceDrawCall{clientCall: call, writeStream: implDrawInterfaceDrawStreamSender{clientCall: call}, readStream: implDrawInterfaceDrawStreamIterator{clientCall: call}}
- return
-}
-
-func (__gen_c *clientStubDrawInterface) SyncBoxes(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "SyncBoxes", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubDrawInterface) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubDrawInterface) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubDrawInterface) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubDrawInterface wraps a server that implements
-// DrawInterfaceService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubDrawInterface struct {
- service DrawInterfaceService
-}
-
-func (__gen_s *ServerStubDrawInterface) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Draw":
- return []interface{}{}, nil
- case "SyncBoxes":
- return []interface{}{}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubDrawInterface) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Draw"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "Err", Type: 65},
- },
- InStream: 67,
- OutStream: 67,
- }
- result.Methods["SyncBoxes"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "Err", Type: 65},
- },
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.ArrayType{Elem: 0x19, Len: 0x4, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x3, Name: "DeviceId"},
- _gen_wiretype.FieldType{Type: 0x3, Name: "BoxId"},
- _gen_wiretype.FieldType{Type: 0x42, Name: "Points"},
- },
- "veyron/examples/boxes.Box", []string(nil)},
- }
-
- return result, nil
-}
-
-func (__gen_s *ServerStubDrawInterface) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubDrawInterface) Draw(call _gen_ipc.ServerCall) (err error) {
- stream := &implDrawInterfaceServiceDrawStream{reader: implDrawInterfaceServiceDrawStreamIterator{serverCall: call}, writer: implDrawInterfaceServiceDrawStreamSender{serverCall: call}}
- err = __gen_s.service.Draw(call, stream)
- return
-}
-
-func (__gen_s *ServerStubDrawInterface) SyncBoxes(call _gen_ipc.ServerCall) (err error) {
- err = __gen_s.service.SyncBoxes(call)
- return
-}
diff --git a/examples/boxes/signallingserver/main.go b/examples/boxes/signallingserver/main.go
deleted file mode 100644
index 97058d3..0000000
--- a/examples/boxes/signallingserver/main.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Binary signallingserver is a simple implementation of the BoxSignalling
-// rendezvous service.
-package main
-
-import (
- "log"
- "strings"
-
- "veyron/examples/boxes"
- "veyron/lib/signals"
-
- "veyron2/ipc"
- "veyron2/rt"
- "veyron2/security"
-)
-
-const (
- signallingServiceName = "signalling"
- signallingServicePort = ":8509"
-)
-
-type boxAppEndpoint string
-
-func (b *boxAppEndpoint) Add(_ ipc.ServerContext, Endpoint string) (err error) {
- *b = boxAppEndpoint(Endpoint)
- log.Printf("Added endpoint %v to signalling service", *b)
- return nil
-}
-
-func (b *boxAppEndpoint) Get(_ ipc.ServerContext) (Endpoint string, err error) {
- log.Printf("Returning endpoints:%v from signalling service", *b)
- return string(*b), nil
-}
-
-type dispatcher struct {
- invoker ipc.Invoker
-}
-
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
- suffix = strings.TrimPrefix(suffix, signallingServiceName)
- return d.invoker, nil, nil
-}
-
-func main() {
- r := rt.Init()
-
- // Create a new server instance.
- s, err := r.NewServer()
- if err != nil {
- log.Fatal("failed NewServer: ", err)
- }
-
- var boxApp boxAppEndpoint
- srv := boxes.NewServerBoxSignalling(&boxApp)
-
- // Create an endpoint and begin listening.
- if endPt, err := s.Listen("tcp", signallingServicePort); err == nil {
- log.Printf("SignallingService listening at: %v\n", endPt)
- } else {
- log.Fatal("failed Listen: ", err)
- }
-
- if err := s.Serve("", &dispatcher{ipc.ReflectInvoker(srv)}); err != nil {
- log.Fatal("failed Serve:", err)
- }
-
- <-signals.ShutdownOnSignals()
-}
diff --git a/examples/fortune/doc.go b/examples/fortune/doc.go
deleted file mode 100644
index a8a09f9..0000000
--- a/examples/fortune/doc.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// Package fortune contains the most basic client/server application using the
-// Veyron API. See http://go/veyron:code-lab for a thorough walk-through.
-package fortune
diff --git a/examples/fortune/fortune.vdl b/examples/fortune/fortune.vdl
deleted file mode 100644
index 7df86e2..0000000
--- a/examples/fortune/fortune.vdl
+++ /dev/null
@@ -1,11 +0,0 @@
-package fortune
-
-import "veyron2/security"
-
-// Fortune allows clients to Get and Add fortune strings.
-type Fortune interface {
- // Get returns a random fortune.
- Get() (Fortune string, Err error) {security.ReadLabel}
- // Add stores a fortune in the set used by Get.
- Add(Fortune string) error {security.WriteLabel}
-}
diff --git a/examples/fortune/fortune.vdl.go b/examples/fortune/fortune.vdl.go
deleted file mode 100644
index 1651ebb..0000000
--- a/examples/fortune/fortune.vdl.go
+++ /dev/null
@@ -1,219 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: fortune.vdl
-
-package fortune
-
-import (
- "veyron2/security"
-
- // The non-user imports are prefixed with "_gen_" to prevent collisions.
- _gen_veyron2 "veyron2"
- _gen_context "veyron2/context"
- _gen_ipc "veyron2/ipc"
- _gen_naming "veyron2/naming"
- _gen_vdlutil "veyron2/vdl/vdlutil"
- _gen_wiretype "veyron2/wiretype"
-)
-
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
-const _ = _gen_wiretype.TypeIDInvalid
-
-// Fortune allows clients to Get and Add fortune strings.
-// Fortune is the interface the client binds and uses.
-// Fortune_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type Fortune_ExcludingUniversal interface {
- // Get returns a random fortune.
- Get(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply string, err error)
- // Add stores a fortune in the set used by Get.
- Add(ctx _gen_context.T, Fortune string, opts ..._gen_ipc.CallOpt) (err error)
-}
-type Fortune interface {
- _gen_ipc.UniversalServiceMethods
- Fortune_ExcludingUniversal
-}
-
-// FortuneService is the interface the server implements.
-type FortuneService interface {
-
- // Get returns a random fortune.
- Get(context _gen_ipc.ServerContext) (reply string, err error)
- // Add stores a fortune in the set used by Get.
- Add(context _gen_ipc.ServerContext, Fortune string) (err error)
-}
-
-// BindFortune returns the client stub implementing the Fortune
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindFortune(name string, opts ..._gen_ipc.BindOpt) (Fortune, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubFortune{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerFortune creates a new server stub.
-//
-// It takes a regular server implementing the FortuneService
-// interface, and returns a new server stub.
-func NewServerFortune(server FortuneService) interface{} {
- return &ServerStubFortune{
- service: server,
- }
-}
-
-// clientStubFortune implements Fortune.
-type clientStubFortune struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubFortune) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubFortune) Get(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Get", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubFortune) Add(ctx _gen_context.T, Fortune string, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Add", []interface{}{Fortune}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubFortune) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubFortune) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubFortune) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubFortune wraps a server that implements
-// FortuneService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubFortune struct {
- service FortuneService
-}
-
-func (__gen_s *ServerStubFortune) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Get":
- return []interface{}{security.Label(2)}, nil
- case "Add":
- return []interface{}{security.Label(4)}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubFortune) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Add"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "Fortune", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["Get"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "Fortune", Type: 3},
- {Name: "Err", Type: 65},
- },
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
-
- return result, nil
-}
-
-func (__gen_s *ServerStubFortune) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubFortune) Get(call _gen_ipc.ServerCall) (reply string, err error) {
- reply, err = __gen_s.service.Get(call)
- return
-}
-
-func (__gen_s *ServerStubFortune) Add(call _gen_ipc.ServerCall, Fortune string) (err error) {
- err = __gen_s.service.Add(call, Fortune)
- return
-}
diff --git a/examples/fortune/fortune/main.go b/examples/fortune/fortune/main.go
deleted file mode 100644
index 559ef1a..0000000
--- a/examples/fortune/fortune/main.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Binary fortune is a simple client of the fortune service. See
-// http://go/veyron:code-lab for a thorough explanation.
-package main
-
-import (
- "flag"
- "fmt"
- "time"
-
- "veyron/examples/fortune"
-
- "veyron2"
- "veyron2/naming"
- "veyron2/rt"
- "veyron2/security"
-)
-
-var (
- // TODO(rthellend): Remove the address flag when the config manager is working.
- address = flag.String("address", "", "the address/endpoint of the fortune server")
- newFortune = flag.String("new_fortune", "", "an optional, new fortune to add to the server's set")
- serverPattern = flag.String("server_pattern", string(security.AllPrincipals), "server_pattern is an optional pattern for the expected identity of the fortune server. Example: the pattern \"myorg/fortune\" matches identities with names \"myorg/fortune\" or \"myorg\". If the flag is absent then the default pattern \"...\" matches all identities.")
-)
-
-func main() {
- runtime := rt.Init()
- log := runtime.Logger()
- if *address == "" {
- log.Fatal("--address needs to be specified")
- }
-
- // Construct a new stub that binds to serverEndpoint without
- // using the name service
- s, err := fortune.BindFortune(naming.JoinAddressName(*address, ""))
- if err != nil {
- log.Fatal("error binding to server: ", err)
- }
-
- // Issue a Get() rpc specifying the provided pattern for the server's identity as
- // an option. If no pattern is provided then the default pattern "..." matches all
- // identities.
- ctx, cancel := runtime.NewContext().WithTimeout(time.Minute)
- defer cancel()
-
- fortune, err := s.Get(ctx, veyron2.RemoteID(*serverPattern))
- if err != nil {
- log.Fatal("error getting fortune: ", err)
- }
- fmt.Println(fortune)
-
- // If the user specified --new_fortune, Add() it to the server’s set of fortunes.
- // Again, the provided pattern on the server's identity is passed as an option.
- if *newFortune != "" {
- if err := s.Add(ctx, *newFortune, veyron2.RemoteID(*serverPattern)); err != nil {
- log.Fatal("error adding fortune: ", err)
- }
- }
-}
diff --git a/examples/fortune/fortuned/main.go b/examples/fortune/fortuned/main.go
deleted file mode 100644
index 2cce124..0000000
--- a/examples/fortune/fortuned/main.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Binary fortuned is a simple implementation of the fortune service. See
-// http://go/veyron:code-lab for a thorough explanation.
-package main
-
-import (
- "fmt"
- "log"
- "math/rand"
-
- "veyron/examples/fortune"
- "veyron/lib/signals"
- vflag "veyron/security/flag"
-
- "veyron2/ipc"
- "veyron2/rt"
-)
-
-type fortuned struct {
- // The set of all fortunes.
- fortunes []string
- // Used to pick a random index in 'fortunes'.
- random *rand.Rand
-}
-
-// newFortuned creates a new fortuned and seeds it with a few fortunes.
-func newFortuned() *fortuned {
- return &fortuned{
- fortunes: []string{
- "You will reach the height of success in whatever you do.",
- "You have remarkable power which you are not using.",
- "Everything will now come your way.",
- },
- random: rand.New(rand.NewSource(99)),
- }
-}
-
-func (f *fortuned) Get(_ ipc.ServerContext) (Fortune string, err error) {
- return f.fortunes[f.random.Intn(len(f.fortunes))], nil
-}
-
-func (f *fortuned) Add(_ ipc.ServerContext, Fortune string) error {
- f.fortunes = append(f.fortunes, Fortune)
- return nil
-}
-
-func main() {
- // Create the runtime
- r := rt.Init()
-
- // Create a new server instance.
- s, err := r.NewServer()
- if err != nil {
- log.Fatal("failure creating server: ", err)
- }
-
- // Create the fortune server stub.
- serverFortune := fortune.NewServerFortune(newFortuned())
-
- // Create an endpoint and begin listening.
- if endpoint, err := s.Listen("tcp", "127.0.0.1:0"); err == nil {
- fmt.Printf("Listening at: %v\n", endpoint)
- } else {
- log.Fatal("error listening to service: ", err)
- }
-
- // Serve the fortune dispatcher, but don't publish its existence
- // to a mount table.
- if err := s.Serve("", ipc.LeafDispatcher(serverFortune, vflag.NewAuthorizerOrDie())); err != nil {
- log.Fatal("error serving service: ", err)
- }
-
- // Wait forever.
- <-signals.ShutdownOnSignals()
-}
diff --git a/examples/inspector/inspector.vdl b/examples/inspector/inspector.vdl
deleted file mode 100644
index adeb0ad..0000000
--- a/examples/inspector/inspector.vdl
+++ /dev/null
@@ -1,18 +0,0 @@
-package inspector
-
-type Details struct {
- Name string
- Size int64
- Mode uint32
- // TODO: add native time format to the idl+vom
- // Seconds since the start of the Unix epoch
- ModUnixSecs int64
- // Nanoseconds in the current second
- ModNano int32
- IsDir bool
-}
-
-type Inspector interface {
- Ls(Glob string) stream<_, string> error
- LsDetails(Glob string) stream<_, Details> error
-}
diff --git a/examples/inspector/inspector.vdl.go b/examples/inspector/inspector.vdl.go
deleted file mode 100644
index 15bdca7..0000000
--- a/examples/inspector/inspector.vdl.go
+++ /dev/null
@@ -1,478 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: inspector.vdl
-
-package inspector
-
-import (
- // The non-user imports are prefixed with "_gen_" to prevent collisions.
- _gen_io "io"
- _gen_veyron2 "veyron2"
- _gen_context "veyron2/context"
- _gen_ipc "veyron2/ipc"
- _gen_naming "veyron2/naming"
- _gen_vdlutil "veyron2/vdl/vdlutil"
- _gen_wiretype "veyron2/wiretype"
-)
-
-type Details struct {
- Name string
- Size int64
- Mode uint32
- // TODO: add native time format to the idl+vom
- // Seconds since the start of the Unix epoch
- ModUnixSecs int64
- // Nanoseconds in the current second
- ModNano int32
- IsDir bool
-}
-
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
-const _ = _gen_wiretype.TypeIDInvalid
-
-// Inspector is the interface the client binds and uses.
-// Inspector_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type Inspector_ExcludingUniversal interface {
- Ls(ctx _gen_context.T, Glob string, opts ..._gen_ipc.CallOpt) (reply InspectorLsCall, err error)
- LsDetails(ctx _gen_context.T, Glob string, opts ..._gen_ipc.CallOpt) (reply InspectorLsDetailsCall, err error)
-}
-type Inspector interface {
- _gen_ipc.UniversalServiceMethods
- Inspector_ExcludingUniversal
-}
-
-// InspectorService is the interface the server implements.
-type InspectorService interface {
- Ls(context _gen_ipc.ServerContext, Glob string, stream InspectorServiceLsStream) (err error)
- LsDetails(context _gen_ipc.ServerContext, Glob string, stream InspectorServiceLsDetailsStream) (err error)
-}
-
-// InspectorLsCall is the interface for call object of the method
-// Ls in the service interface Inspector.
-type InspectorLsCall interface {
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() string
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-
- // Finish blocks until the server is done and returns the positional
- // return values for call.
- //
- // If Cancel has been called, Finish will return immediately; the output of
- // Finish could either be an error signalling cancelation, or the correct
- // positional return values from the server depending on the timing of the
- // call.
- //
- // Calling Finish is mandatory for releasing stream resources, unless Cancel
- // has been called or any of the other methods return an error.
- // Finish should be called at most once.
- Finish() (err error)
-
- // Cancel cancels the RPC, notifying the server to stop processing. It
- // is safe to call Cancel concurrently with any of the other stream methods.
- // Calling Cancel after Finish has returned is a no-op.
- Cancel()
-}
-
-type implInspectorLsStreamIterator struct {
- clientCall _gen_ipc.Call
- val string
- err error
-}
-
-func (c *implInspectorLsStreamIterator) Advance() bool {
- c.err = c.clientCall.Recv(&c.val)
- return c.err == nil
-}
-
-func (c *implInspectorLsStreamIterator) Value() string {
- return c.val
-}
-
-func (c *implInspectorLsStreamIterator) Err() error {
- if c.err == _gen_io.EOF {
- return nil
- }
- return c.err
-}
-
-// Implementation of the InspectorLsCall interface that is not exported.
-type implInspectorLsCall struct {
- clientCall _gen_ipc.Call
- readStream implInspectorLsStreamIterator
-}
-
-func (c *implInspectorLsCall) RecvStream() interface {
- Advance() bool
- Value() string
- Err() error
-} {
- return &c.readStream
-}
-
-func (c *implInspectorLsCall) Finish() (err error) {
- if ierr := c.clientCall.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (c *implInspectorLsCall) Cancel() {
- c.clientCall.Cancel()
-}
-
-type implInspectorServiceLsStreamSender struct {
- serverCall _gen_ipc.ServerCall
-}
-
-func (s *implInspectorServiceLsStreamSender) Send(item string) error {
- return s.serverCall.Send(item)
-}
-
-// InspectorServiceLsStream is the interface for streaming responses of the method
-// Ls in the service interface Inspector.
-type InspectorServiceLsStream interface {
- // SendStream returns the send portion of the stream.
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item string) error
- }
-}
-
-// Implementation of the InspectorServiceLsStream interface that is not exported.
-type implInspectorServiceLsStream struct {
- writer implInspectorServiceLsStreamSender
-}
-
-func (s *implInspectorServiceLsStream) SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item string) error
-} {
- return &s.writer
-}
-
-// InspectorLsDetailsCall is the interface for call object of the method
-// LsDetails in the service interface Inspector.
-type InspectorLsDetailsCall interface {
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() Details
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-
- // Finish blocks until the server is done and returns the positional
- // return values for call.
- //
- // If Cancel has been called, Finish will return immediately; the output of
- // Finish could either be an error signalling cancelation, or the correct
- // positional return values from the server depending on the timing of the
- // call.
- //
- // Calling Finish is mandatory for releasing stream resources, unless Cancel
- // has been called or any of the other methods return an error.
- // Finish should be called at most once.
- Finish() (err error)
-
- // Cancel cancels the RPC, notifying the server to stop processing. It
- // is safe to call Cancel concurrently with any of the other stream methods.
- // Calling Cancel after Finish has returned is a no-op.
- Cancel()
-}
-
-type implInspectorLsDetailsStreamIterator struct {
- clientCall _gen_ipc.Call
- val Details
- err error
-}
-
-func (c *implInspectorLsDetailsStreamIterator) Advance() bool {
- c.val = Details{}
- c.err = c.clientCall.Recv(&c.val)
- return c.err == nil
-}
-
-func (c *implInspectorLsDetailsStreamIterator) Value() Details {
- return c.val
-}
-
-func (c *implInspectorLsDetailsStreamIterator) Err() error {
- if c.err == _gen_io.EOF {
- return nil
- }
- return c.err
-}
-
-// Implementation of the InspectorLsDetailsCall interface that is not exported.
-type implInspectorLsDetailsCall struct {
- clientCall _gen_ipc.Call
- readStream implInspectorLsDetailsStreamIterator
-}
-
-func (c *implInspectorLsDetailsCall) RecvStream() interface {
- Advance() bool
- Value() Details
- Err() error
-} {
- return &c.readStream
-}
-
-func (c *implInspectorLsDetailsCall) Finish() (err error) {
- if ierr := c.clientCall.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (c *implInspectorLsDetailsCall) Cancel() {
- c.clientCall.Cancel()
-}
-
-type implInspectorServiceLsDetailsStreamSender struct {
- serverCall _gen_ipc.ServerCall
-}
-
-func (s *implInspectorServiceLsDetailsStreamSender) Send(item Details) error {
- return s.serverCall.Send(item)
-}
-
-// InspectorServiceLsDetailsStream is the interface for streaming responses of the method
-// LsDetails in the service interface Inspector.
-type InspectorServiceLsDetailsStream interface {
- // SendStream returns the send portion of the stream.
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item Details) error
- }
-}
-
-// Implementation of the InspectorServiceLsDetailsStream interface that is not exported.
-type implInspectorServiceLsDetailsStream struct {
- writer implInspectorServiceLsDetailsStreamSender
-}
-
-func (s *implInspectorServiceLsDetailsStream) SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item Details) error
-} {
- return &s.writer
-}
-
-// BindInspector returns the client stub implementing the Inspector
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindInspector(name string, opts ..._gen_ipc.BindOpt) (Inspector, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubInspector{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerInspector creates a new server stub.
-//
-// It takes a regular server implementing the InspectorService
-// interface, and returns a new server stub.
-func NewServerInspector(server InspectorService) interface{} {
- return &ServerStubInspector{
- service: server,
- }
-}
-
-// clientStubInspector implements Inspector.
-type clientStubInspector struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubInspector) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubInspector) Ls(ctx _gen_context.T, Glob string, opts ..._gen_ipc.CallOpt) (reply InspectorLsCall, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Ls", []interface{}{Glob}, opts...); err != nil {
- return
- }
- reply = &implInspectorLsCall{clientCall: call, readStream: implInspectorLsStreamIterator{clientCall: call}}
- return
-}
-
-func (__gen_c *clientStubInspector) LsDetails(ctx _gen_context.T, Glob string, opts ..._gen_ipc.CallOpt) (reply InspectorLsDetailsCall, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "LsDetails", []interface{}{Glob}, opts...); err != nil {
- return
- }
- reply = &implInspectorLsDetailsCall{clientCall: call, readStream: implInspectorLsDetailsStreamIterator{clientCall: call}}
- return
-}
-
-func (__gen_c *clientStubInspector) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubInspector) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubInspector) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubInspector wraps a server that implements
-// InspectorService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubInspector struct {
- service InspectorService
-}
-
-func (__gen_s *ServerStubInspector) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Ls":
- return []interface{}{}, nil
- case "LsDetails":
- return []interface{}{}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubInspector) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Ls"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "Glob", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
-
- OutStream: 3,
- }
- result.Methods["LsDetails"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "Glob", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
-
- OutStream: 66,
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x3, Name: "Name"},
- _gen_wiretype.FieldType{Type: 0x25, Name: "Size"},
- _gen_wiretype.FieldType{Type: 0x34, Name: "Mode"},
- _gen_wiretype.FieldType{Type: 0x25, Name: "ModUnixSecs"},
- _gen_wiretype.FieldType{Type: 0x24, Name: "ModNano"},
- _gen_wiretype.FieldType{Type: 0x2, Name: "IsDir"},
- },
- "veyron/examples/inspector.Details", []string(nil)},
- }
-
- return result, nil
-}
-
-func (__gen_s *ServerStubInspector) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubInspector) Ls(call _gen_ipc.ServerCall, Glob string) (err error) {
- stream := &implInspectorServiceLsStream{writer: implInspectorServiceLsStreamSender{serverCall: call}}
- err = __gen_s.service.Ls(call, Glob, stream)
- return
-}
-
-func (__gen_s *ServerStubInspector) LsDetails(call _gen_ipc.ServerCall, Glob string) (err error) {
- stream := &implInspectorServiceLsDetailsStream{writer: implInspectorServiceLsDetailsStreamSender{serverCall: call}}
- err = __gen_s.service.LsDetails(call, Glob, stream)
- return
-}
diff --git a/examples/inspector/inspector/main.go b/examples/inspector/inspector/main.go
deleted file mode 100644
index 5937e7d..0000000
--- a/examples/inspector/inspector/main.go
+++ /dev/null
@@ -1,192 +0,0 @@
-// This example client illustrates how to use both the IDL stubbed API for
-// talking to a simple service (inspector) as well as the stubbles API.
-// It decides which to use based on the name of the service. If the name
-// contains a component (anywhere with it, other than the address)
-// "stubbed" then it will use the IDL stubs or if it contains a component
-// "stubless" then it will use the naked API. If neither is found then
-// an error encountered.
-// The inspector service supports three subtrees: files, proc and dev
-// representing the file system, /proc and /dev on the target system. The
-// filesystem is relative to the current working directory of the server.
-// The client will list either just the names, or optionally (-l) various
-// metadata for each item returned.
-// The results are streamed back to the client.
-package main
-
-import (
- "flag"
- "fmt"
- "io"
- "os"
- "strings"
- "time"
-
- "veyron2/ipc"
- "veyron2/naming"
- "veyron2/rt"
- "veyron2/vlog"
-
- "veyron/lib/signals"
-
- "veyron/examples/inspector"
-)
-
-var (
- service string
- glob string
- details bool
-)
-
-func init() {
- flag.StringVar(&service, "service", "", "service to use")
- flag.StringVar(&glob, "glob", "", "glob")
- flag.BoolVar(&details, "l", false, "details")
-}
-
-func main() {
- rt.Init()
- _, name := naming.SplitAddressName(service)
- // The presence of a name component of 'stubbed' or 'stubless'
- // determines whether the client should use IDL stubs or not.
- for _, component := range strings.Split(name, "/") {
- switch component {
- case "stubbed":
- stubbed()
- return
- case "stubless":
- stubless()
- return
- }
- }
- fmt.Fprintf(os.Stderr, "need to use one of '.../stubbed/...' or '.../stubless/...'\n")
- os.Exit(1)
-}
-
-// ls and lsdashl are idiomatic for use without stubs
-func ls(call ipc.Call) {
- for {
- var n string
- if err := call.Recv(&n); err != nil {
- if err == io.EOF {
- break
- }
- vlog.Fatalf("unexpected streaming error: %q", err)
- } else {
- fmt.Printf("%s\n", n)
- }
- }
-}
-
-func lsdashl(call ipc.Call) {
- type details struct {
- Name string
- Size int64
- Mode os.FileMode
- ModTime time.Time
- IsDir bool
- }
- for {
- var n details
- if err := call.Recv(&n); err != nil {
- if err == io.EOF {
- break
- }
- vlog.Fatalf("unexpected streaming error: %q", err)
- } else {
- fmt.Printf("%s: %d %s %s%s\n", n.Name, n.Size, n.Mode, n.ModTime, map[bool]string{false: "", true: "/"}[n.IsDir])
- }
- }
-}
-
-func stubless() {
- client, err := rt.R().NewClient()
- if err != nil {
- vlog.Fatalf("failed to create new client: %q", err)
- }
- defer client.Close()
-
- ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
- defer cancel()
-
- call, err := client.StartCall(ctx, service, "List", []interface{}{glob, details})
- if err != nil {
- vlog.Fatalf("failed to start call: %q", err)
- }
- go func() {
- <-signals.ShutdownOnSignals()
- call.Cancel()
- }()
- if details {
- lsdashl(call)
- } else {
- ls(call)
- }
- var verr error
- if err := call.Finish(&verr); err != nil && err != io.EOF {
- vlog.Fatalf("%q", err)
- }
- if verr != nil {
- vlog.Fatalf("%q", verr)
- }
-}
-
-// streamNames and streamDetails are idiomatic for use with stubs
-func streamNames(stream inspector.InspectorLsCall) {
- rStream := stream.RecvStream()
- for rStream.Advance() {
- name := rStream.Value()
- fmt.Printf("%s\n", name)
- }
-
- if err := rStream.Err(); err != nil {
- vlog.Fatalf("unexpected streaming error: %q", err)
- }
- if err := stream.Finish(); err != nil && err != io.EOF {
- vlog.Fatalf("%q", err)
- }
-}
-
-func streamDetails(stream inspector.InspectorLsDetailsCall) {
- rStream := stream.RecvStream()
- for rStream.Advance() {
- details := rStream.Value()
- mode := os.FileMode(details.Mode)
- modtime := time.Unix(details.ModUnixSecs, int64(details.ModNano))
- fmt.Printf("%s: %d %s %s%s\n", details.Name, details.Size, mode, modtime, map[bool]string{false: "", true: "/"}[details.IsDir])
- }
-
- if err := rStream.Err(); err != nil {
- vlog.Fatalf("unexpected streaming error: %q", err)
- }
-
- if err := stream.Finish(); err != nil && err != io.EOF {
- vlog.Fatalf("%q", err)
- }
-
-}
-
-func stubbed() {
- inspector, err := inspector.BindInspector(service)
- if err != nil {
- vlog.Fatalf("failed to create new client: %q", err)
- }
- bail := func(err error) {
- vlog.Fatalf("failed to start call: %q", err)
- }
- ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
- defer cancel()
- if details {
- if stream, err := inspector.LsDetails(ctx, glob); err != nil {
- bail(err)
- } else {
- streamDetails(stream)
- }
- } else {
- if stream, err := inspector.Ls(ctx, glob); err != nil {
- bail(err)
- } else {
- streamNames(stream)
- }
- }
- // TODO(cnicolaou): stubs need to expose cancel method.
-}
diff --git a/examples/inspector/inspector/test.sh b/examples/inspector/inspector/test.sh
deleted file mode 100755
index 4faaa49..0000000
--- a/examples/inspector/inspector/test.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-
-source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
-
-build() {
- local -r GO="${REPO_ROOT}/scripts/build/go"
- "${GO}" build veyron/examples/inspector/inspector || shell_test::fail "line ${LINENO}: failed to build inspector"
- "${GO}" build veyron/examples/inspector/inspectord || shell_test::fail "line ${LINENO}: failed to build inspectord"
- "${GO}" build veyron/tools/identity || shell_test::fail "line ${LINENO}: failed to build identity"
-}
-
-main() {
- cd "${TMPDIR}"
- build
-
- # Generate an identity for the client and server
- # For now, using the same one for both
- local -r ID="${TMPDIR}/id"
- ./identity generate inspector >"${ID}" || shell_test::fail "line ${LINENO}: failed to generate an identity"
- export VEYRON_IDENTITY="${ID}"
-
- ./inspectord --address=127.0.0.1:0 >ep &
- for i in 1 2 3 4; do
- local EP=$(cat ep)
- if [[ -n "${EP}" ]]; then
- break
- fi
- sleep "${i}"
- done
- [[ -z "${EP}" ]] && shell_test::fail "line ${LINENO}: no inspectord"
-
- ./inspector --service "/${EP}/stubbed/files" -glob='m*' || shell_test::fail "line ${LINENO}: stubbed/files"
- ./inspector --service "/${EP}/stubless/files" -glob='m*'|| shell_test::fail "line ${LINENO}: stubless/files"
-
- shell_test::pass
-}
-
-main "$@"
diff --git a/examples/inspector/inspectord/main.go b/examples/inspector/inspectord/main.go
deleted file mode 100644
index b3307c1..0000000
--- a/examples/inspector/inspectord/main.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "os"
-
- "veyron2"
- "veyron2/rt"
- "veyron2/vlog"
-)
-
-var (
- log vlog.Logger
- r veyron2.Runtime
-
- // TODO(rthellend): Remove the protocol and address flags when the config
- // manager is working.
- protocol = flag.String("protocol", "tcp", "protocol to listen on")
- address = flag.String("address", ":0", "address to listen on")
-)
-
-func main() {
- r = rt.Init()
- log = r.Logger()
- hostname, _ := os.Hostname()
- server, err := r.NewServer()
- if err != nil {
- log.Fatalf("failed to create server: %q", err)
- }
- ep, err := server.Listen(*protocol, *address)
- if err != nil {
- log.Fatalf("listen failed: %q", err)
- }
- if err := server.Serve(hostname, &dispatcher{}); err != nil {
- log.Fatalf("failed to register %q: %q\n", hostname, err)
- }
- defer server.Stop()
- fmt.Printf("%s\n", ep)
- // Wait forever.
- done := make(chan struct{})
- <-done
-}
diff --git a/examples/inspector/inspectord/services.go b/examples/inspector/inspectord/services.go
deleted file mode 100644
index 87fbe5b..0000000
--- a/examples/inspector/inspectord/services.go
+++ /dev/null
@@ -1,239 +0,0 @@
-package main
-
-import (
- "fmt"
- "io"
- "os"
- "path/filepath"
- "strings"
- "time"
-
- "veyron2/ipc"
- "veyron2/security"
-
- "veyron/examples/inspector"
-)
-
-// There are three service types: files, /proc and /dev.
-type serviceType int
-
-const (
- fileSvc serviceType = iota
- procSvc
- deviceSvc
-)
-
-// Dispatchers create servers, based on the names used. Dispatchers
-// create stubbed or stubless servers.
-type dispatcher struct{}
-
-// A service represents one of the file, proc or device service
-type server struct {
- service serviceType
- root, suffix string
-}
-
-// ServerInterface defines the common methods that both stubbed and stubless
-// implementations must provided.
-type serverInterface interface {
- send(fi os.FileInfo, details bool) error
- cancelled() bool
-}
-
-type stublessServer struct {
- call ipc.ServerCall
-}
-
-func (s *stublessServer) send(fi os.FileInfo, details bool) error {
- if !details {
- return s.call.Send(fi.Name())
- }
- d := struct {
- Name string
- Size int64
- Mode os.FileMode
- ModTime time.Time
- IsDir bool
- }{
- Name: fi.Name(),
- Size: fi.Size(),
- Mode: fi.Mode(),
- ModTime: fi.ModTime(),
- IsDir: fi.IsDir(),
- }
- return s.call.Send(d)
-}
-
-func (s *stublessServer) cancelled() bool {
- select {
- case <-s.call.Done():
- return true
- default:
- return false
- }
-}
-
-type stubbedServer struct {
- context ipc.ServerContext
- names inspector.InspectorServiceLsStream
- details inspector.InspectorServiceLsDetailsStream
-}
-
-func (s *stubbedServer) send(fi os.FileInfo, details bool) error {
- if !details {
- return s.names.SendStream().Send(fi.Name())
- }
- return s.details.SendStream().Send(inspector.Details{
- Name: fi.Name(),
- Size: fi.Size(),
- Mode: uint32(fi.Mode()),
- ModUnixSecs: fi.ModTime().Unix(),
- ModNano: int32(fi.ModTime().Nanosecond()),
- IsDir: fi.IsDir(),
- })
-}
-
-func (s *stubbedServer) cancelled() bool {
- select {
- case <-s.context.Done():
- return true
- default:
- return false
- }
-}
-
-// ls is shared by both stubbed and stubless calls and contains
-// the bulk of the actual server code.
-func (s *server) ls(glob string, details bool, impl serverInterface) error {
- // validate the glob pattern
- if _, err := filepath.Match(glob, ""); err != nil {
- return err
- }
- ch := make(chan []os.FileInfo, 10)
- errch := make(chan error, 1)
- go readdir(filepath.Join(s.root, s.suffix), glob, ch, errch)
- for {
- select {
- case fs := <-ch:
- if len(fs) == 0 {
- return nil
- }
- for _, f := range fs {
- if err := impl.send(f, details); err != nil {
- return err
- }
- }
- case err := <-errch:
- // Flush any buffered data in the data channel when
- // an error is encountered.
- for fs := range ch {
- for _, f := range fs {
- impl.send(f, details)
- }
- }
- return err
- case <-time.After(time.Second):
- return fmt.Errorf("timed out reading info")
- }
- if impl.cancelled() {
- // TODO(cnicolaou): we most likely need to flush
- // and clear channels here, otherwise we're leaking
- // goroutines and channels.
- // TODO(cnicolaou): test this...
- return fmt.Errorf("cancelled")
- }
- }
- return nil
-}
-
-// Ls is a stubbed server method
-func (s *server) Ls(context ipc.ServerContext, Glob string, Stream inspector.InspectorServiceLsStream) error {
- log.Infof("Ls %q", Glob)
- return s.ls(Glob, false, &stubbedServer{context: context, names: Stream})
-}
-
-// LsDetails is a stubbed server method
-func (s *server) LsDetails(context ipc.ServerContext, Glob string, Stream inspector.InspectorServiceLsDetailsStream) error {
- log.Infof("LsDetails %q", Glob)
- return s.ls(Glob, true, &stubbedServer{context: context, details: Stream})
-}
-
-type stubwrapper struct {
- s *server
-}
-
-// List is a stubless server method
-func (s *stubwrapper) List(call ipc.ServerCall, glob string, details bool) error {
- log.Infof("List: %q details %t", glob, details)
- return s.s.ls(glob, details, &stublessServer{call})
-}
-
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
- s := &server{}
- cwd, err := os.Getwd()
- if err != nil {
- return nil, nil, err
- }
- switch {
- case strings.HasPrefix(suffix, "stubbed/files"):
- s.root = cwd
- s.suffix = strings.TrimPrefix(suffix, "stubbed/files")
- return ipc.ReflectInvoker(inspector.NewServerInspector(s)), nil, nil
- case strings.HasPrefix(suffix, "stubbed/proc"):
- s.root = "/proc"
- s.suffix = strings.TrimPrefix(suffix, "stubbed/proc")
- return ipc.ReflectInvoker(inspector.NewServerInspector(s)), nil, nil
- case strings.HasPrefix(suffix, "stubbed/devices"):
- s.root = "/dev"
- s.suffix = strings.TrimPrefix(suffix, "stubbed/devices")
- return ipc.ReflectInvoker(inspector.NewServerInspector(s)), nil, nil
- case strings.HasPrefix(suffix, "stubless/files"):
- s.root = cwd
- s.suffix = strings.TrimPrefix(suffix, "stubless/files")
- return ipc.ReflectInvoker(&stubwrapper{s}), nil, nil
- case strings.HasPrefix(suffix, "stubless/proc"):
- s.root = "/dev"
- s.suffix = strings.TrimPrefix(suffix, "stubless/proc")
- return ipc.ReflectInvoker(&stubwrapper{s}), nil, nil
- case strings.HasPrefix(suffix, "stubless/devices"):
- s.root = "/proc"
- s.suffix = strings.TrimPrefix(suffix, "stubless/dev")
- return ipc.ReflectInvoker(s), nil, nil
- default:
- return nil, nil, fmt.Errorf("unrecognised name: %q", suffix)
- }
-}
-
-func readdir(dirname, glob string, ch chan []os.FileInfo, errch chan error) {
- defer close(ch)
- defer close(errch)
- dir, err := os.Open(dirname)
- if err != nil {
- errch <- err
- return
- }
- n := cap(ch)
- for {
- entries, err := dir.Readdir(n)
- if err != nil && err != io.EOF {
- errch <- err
- return
- }
- if len(glob) == 0 {
- ch <- entries
- } else {
- matches := make([]os.FileInfo, 0, len(entries))
- for _, e := range entries {
- if m, _ := filepath.Match(glob, e.Name()); m {
- matches = append(matches, e)
- }
- }
- if len(matches) > 0 {
- ch <- matches
- }
- }
- if err == io.EOF {
- return
- }
- }
-}
diff --git a/examples/mdb/Makefile b/examples/mdb/Makefile
deleted file mode 100644
index 49f36aa..0000000
--- a/examples/mdb/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-build:
- ${VEYRON_ROOT}/veyron/scripts/build/go install veyron/examples/mdb/... veyron/services/mounttable/mounttabled veyron.io/store/veyron/services/store/stored veyron/tools/findunusedport veyron/tools/identity
-
-run: build
- ./run.sh
-
-test:
- ./test.sh
-
-.PHONY: build run test
diff --git a/examples/mdb/README.md b/examples/mdb/README.md
deleted file mode 100644
index 49cfc8d..0000000
--- a/examples/mdb/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# mdb example
-
-A simple "movie database" example of store usage.
-
-## How to run
-
-Simply run `make run`. Under the hood, this generates a self-signed identity,
-starts a mounttable daemon, starts a store daemon, and initializes the store
-with mdb data and templates.
-
-Once everything's up and running, visit the store daemon's viewer in your
-browser (http://localhost:5000 by default) to explore the mdb data.
diff --git a/examples/mdb/mdb_init/main.go b/examples/mdb/mdb_init/main.go
deleted file mode 100644
index dc671eb..0000000
--- a/examples/mdb/mdb_init/main.go
+++ /dev/null
@@ -1,397 +0,0 @@
-// TODO(kash): Rewrite this to use the new dir/object store api.
-// +build ignore
-
-// mdb_init is a tool to initialize the store with an initial database. This is
-// really for demo purposes; in a real database, the contents would be
-// persistent.
-//
-// The contents are loaded from JSON format. See mdb/templates/contents.json
-// for the actual input.
-//
-// Since JSON doesn't support all of the store types, there is a translation
-// phase, where the contents are loaded into a string form, then converted to
-// the mdb/schema schema.
-package main
-
-import (
- "encoding/json"
- "flag"
- "fmt"
- "io/ioutil"
- "os"
- "os/user"
- "path/filepath"
- "strconv"
- "strings"
- "time"
-
- "veyron/examples/mdb/schema"
- "veyron2/context"
- "veyron2/rt"
- "veyron.io/store/veyron2/storage"
- "veyron.io/store/veyron2/storage/vstore"
- "veyron2/vlog"
-)
-
-var (
- storeName string
- templatesDir = flag.String("templates", "templates", "Name of the templates directory")
-
- loadContents = flag.Bool("load-contents", false, "Load contents")
- loadTemplates = flag.Bool("load-templates", false, "Load templates")
- loadAll = flag.Bool("load-all", false, "Load everything")
-)
-
-// Movie is the JSON representation for schema.Movie.
-type Movie struct {
- Image string
- Title string
- Summary string
- Language string
- ReleaseDate string
- Runtime uint
- Genre string
- Director string
-}
-
-// Part is the JSON representation for schema.Part.
-type Part struct {
- Movie string
- Actor string
- Character string
-}
-
-// Person is the JSON representation for schema.Person.
-type Person struct {
- Name string
- BirthDate string
- Image string
-}
-
-// Review is the JSON representation for schema.Review.
-type Review struct {
- Movie string
- Rating uint8
- Text string
-}
-
-// Contents is the JSON object containing the initial store state.
-type Contents struct {
- People map[string]*Person
- Parts map[string]*Part
- Movies map[string]*Movie
- Reviews map[string]*Review
-}
-
-// state is the initial store state.
-type state struct {
- store storage.Store
- ctx context.T // The context to use for all operations.
- storeRoot string // The name of the root of the store.
- tx storage.Transaction // Current transaction; nil if there's no transaction.
- idTable map[string]*value
-}
-
-// value holds the ID and name of a stored value.
-type value struct {
- id storage.ID
- path string
-}
-
-func init() {
- username := "unknown"
- if u, err := user.Current(); err == nil {
- username = u.Username
- }
- hostname := "unknown"
- if h, err := os.Hostname(); err == nil {
- hostname = h
- }
- dir := "global/vstore/" + hostname + "/" + username
- flag.StringVar(&storeName, "store", dir, "Name of the Veyron store")
-}
-
-// parseDate converts from a string data <day>/<month>/<year> UTC to a numeric
-// date represented in nanoseconds since the Unix epoch.
-func parseDate(date string) (int64, error) {
- parts := strings.Split(date, "/")
- if len(parts) != 3 {
- return 0, fmt.Errorf("Bad date: %s", date)
- }
- day, err := strconv.Atoi(parts[0])
- if err != nil {
- return 0, err
- }
- month, err := strconv.Atoi(parts[1])
- if err != nil {
- return 0, err
- }
- year, err := strconv.Atoi(parts[2])
- if err != nil {
- return 0, err
- }
- t := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
- return t.UnixNano(), nil
-}
-
-// parseDuration converts from seconds to nanoseconds.
-func parseDuration(dur uint) int64 {
- return int64(dur) * 1000000000
-}
-
-// newState returns a fresh state.
-func newState(ctx context.T, st storage.Store, storeRoot string) *state {
- return &state{store: st, ctx: ctx, storeRoot: storeRoot, idTable: make(map[string]*value)}
-}
-
-// find fetches a value from the store.
-func (st *state) find(name string) *value {
- return st.idTable[name]
-}
-
-// put adds a value to the store, creating the path to the value if it doesn't
-// already exist.
-func (st *state) put(path string, v interface{}) {
- vlog.Infof("Storing %q = %+v", path, v)
- st.makeParentDirs(path)
- if _, err := st.tx.Bind(path).Put(st.ctx, v); err != nil {
- vlog.Infof("put failed: %s: %s", path, err)
- return
- }
-}
-
-// putNamed adds a value to the store, similar to put, but it also adds the
-// value to the idTable using a symbolic name.
-func (st *state) putNamed(name, path string, v interface{}) {
- vlog.Infof("Storing %s: %q = %+v", name, path, v)
- st.makeParentDirs(path)
- s, err := st.tx.Bind(path).Put(st.ctx, v)
- if err != nil {
- vlog.Infof("Put failed: %s: %s", path, err)
- return
- }
- st.idTable[name] = &value{id: s.ID, path: path}
-}
-
-// makeParentDirs creates the directories in a path if they do not already
-// exist.
-func (st *state) makeParentDirs(path string) {
- l := strings.Split(path, "/")
- for i, _ := range l {
- prefix := filepath.Join(l[:i]...)
- o := st.tx.Bind(prefix)
- if exist, err := o.Exists(st.ctx); err != nil {
- vlog.Infof("Error checking existence at %q: %s", prefix, err)
- } else if !exist {
- if _, err := o.Put(st.ctx, &schema.Dir{}); err != nil {
- vlog.Infof("Error creating parent %q: %s", prefix, err)
- }
- }
- }
-}
-
-// newTransaction starts a new transaction.
-// TODO(kash): Saving the transaction in st is not a good pattern to have in
-// examples. It is better to pass a transaction around than risk the race
-// condition of st being used from multiple threads.
-func (st *state) newTransaction() {
- st.tx = st.store.NewTransaction(st.ctx, st.storeRoot)
-}
-
-// commit commits the current transaction.
-func (st *state) commit() {
- if st.tx == nil {
- vlog.Fatalf("No transaction to commit")
- }
- err := st.tx.Commit(st.ctx)
- st.tx = nil
- if err != nil {
- vlog.Errorf("Failed to commit transaction: %s", err)
- }
-}
-
-// storeContents saves each of the values in the Contents to the store.
-func (st *state) storeContents(c *Contents) {
- for name, p := range c.People {
- st.storePerson(name, p)
- }
- for name, m := range c.Movies {
- st.storeMovie(name, m)
- }
- for name, p := range c.Parts {
- st.storePart(name, p)
- }
- for name, r := range c.Reviews {
- st.storeReview(name, r)
- }
-}
-
-// storePerson saves a schema.Person to the store with the name /people/<Name>.
-func (st *state) storePerson(name string, p *Person) {
- date, err := parseDate(p.BirthDate)
- if err != nil {
- vlog.Infof("Invalid date: %s", err)
- return
- }
- x := &schema.Person{
- Name: p.Name,
- BirthDate: date,
- Image: p.Image,
- }
- path := "/people/" + p.Name
- st.putNamed(name, path, x)
-}
-
-// storeMovie saves a schema.Movie to the store with the name /movie/<Title>.
-func (st *state) storeMovie(name string, m *Movie) {
- releaseDate, err := parseDate(m.ReleaseDate)
- if err != nil {
- vlog.Infof("Invalid date: %s", err)
- return
- }
- runtime := parseDuration(m.Runtime)
- director := st.find(m.Director)
- if director == nil {
- vlog.Infof("Can't find director: %s", m.Director)
- return
- }
- x := &schema.Movie{
- Image: m.Image,
- Title: m.Title,
- Summary: m.Summary,
- Language: m.Language,
- ReleaseDate: releaseDate,
- Runtime: runtime,
- Genre: m.Genre,
- Director: director.id,
- }
- path := "/movies/" + x.Title
- st.putNamed(name, path, x)
-}
-
-// storePart saves a schema.Part to the store, with the name /movie/<Title>/Cast/<id>.
-func (st *state) storePart(name string, p *Part) {
- movie := st.find(p.Movie)
- if movie == nil {
- vlog.Infof("Can't find movie %s", p.Movie)
- return
- }
- actor := st.find(p.Actor)
- if movie == nil {
- vlog.Infof("Can't find actor %s", p.Actor)
- return
- }
- x := &schema.Part{
- Actor: actor.id,
- Character: p.Character,
- }
- path := fmt.Sprintf("%s/Cast/%s", movie.path, name)
- st.putNamed(name, path, x)
-}
-
-// storeReview saves a review to the store, with the name /movie/<Title>/Reviews/<id>.
-func (st *state) storeReview(name string, r *Review) {
- movie := st.find(r.Movie)
- if movie == nil {
- vlog.Infof("Can't find movie %s", r.Movie)
- return
- }
- x := &schema.Review{
- Rating: r.Rating,
- Text: r.Text,
- }
- path := fmt.Sprintf("%s/Reviews/%s", movie.path, name)
- st.putNamed(name, path, x)
-}
-
-// processJSONFile saves the contents of the JSON file to the store.
-func (st *state) processJSONFile(path string) error {
- vlog.Infof("Loading file %s", path)
- file, err := os.Open(path)
- if err != nil {
- return fmt.Errorf("Can't open %q: %s", path, err)
- }
- defer file.Close()
-
- contents := &Contents{}
- decoder := json.NewDecoder(file)
- if err := decoder.Decode(contents); err != nil {
- return fmt.Errorf("Can't decode: %s", err)
- }
-
- st.newTransaction()
- st.storeContents(contents)
- st.commit()
- return nil
-}
-
-// processTemplateFile saves a template file to the store as a string. The name
-// is /templates/<path> where <path> is the filesystem path to the template
-// file.
-func (st *state) processTemplateFile(path, name string) error {
- vlog.Infof("Adding template %s", path)
- s, err := ioutil.ReadFile(path)
- if err != nil {
- return fmt.Errorf("Can't read %q: %s", path, err)
- }
-
- templateName := filepath.ToSlash("templates" + name)
- st.newTransaction()
- st.put(templateName, string(s))
- st.commit()
- return nil
-}
-
-// processRawFile saves the file contents to the store as a string, using the
-// filesystem path as the store name.
-func (st *state) processRawFile(path, name string) error {
- vlog.Infof("Adding raw file %s", path)
- s, err := ioutil.ReadFile(path)
- if err != nil {
- return fmt.Errorf("Can't read %q: %s", path, err)
- }
-
- st.newTransaction()
- st.put(name, string(s))
- st.commit()
- return nil
-}
-
-// processFile stores the contents of the file in the store.
-func (st *state) processFile(path, name string) error {
- switch filepath.Ext(path) {
- case ".json":
- if *loadAll || *loadContents {
- return st.processJSONFile(path)
- }
- case ".tmpl":
- if *loadAll || *loadTemplates {
- return st.processTemplateFile(path, strings.TrimSuffix(name, ".tmpl"))
- }
- case ".css":
- if *loadAll || *loadTemplates {
- return st.processRawFile(path, name)
- }
- }
- return nil
-}
-
-// main reads all the files in the templates directory and adds them to the
-// store.
-func main() {
- r := rt.Init()
-
- vlog.Infof("Binding to store on %s", storeName)
- state := newState(r.NewContext(), vstore.New(), storeName)
-
- // Store all data and templates.
- filepath.Walk(*templatesDir, func(path string, _ os.FileInfo, _ error) error {
- err := state.processFile(path, strings.TrimPrefix(path, *templatesDir))
- if err != nil {
- vlog.Fatalf("Error processing %s: %s", path, err)
- } else {
- vlog.Infof("Processed %s", path)
- }
- return err
- })
-}
diff --git a/examples/mdb/run.sh b/examples/mdb/run.sh
deleted file mode 100755
index 32fca4f..0000000
--- a/examples/mdb/run.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/bash
-
-source "${VEYRON_ROOT}/environment/scripts/lib/shell.sh"
-
-trap at_exit INT TERM EXIT
-
-readonly REPO_ROOT=$(git rev-parse --show-toplevel)
-readonly ID_FILE=$(shell::tmp_file)
-readonly DB_DIR=$(shell::tmp_dir)
-
-at_exit() {
- exec 2>/dev/null
- shell::at_exit # deletes ID_FILE and DB_DIR
- kill -9 $(jobs -p) || true
-}
-
-main() {
- # Used by test.sh to get the store viewer port.
- local VIEWER_PORT_FILE=""
- if [[ "$#" -eq 1 ]]; then
- VIEWER_PORT_FILE="$1"
- fi
- local -r VIEWER_PORT_FILE
- local -r VEYRON_BIN="${REPO_ROOT}/go/bin"
-
- # Generate a self-signed identity.
- "${VEYRON_BIN}/identity" generate > "${ID_FILE}"
-
- # Start the mounttable daemon.
- local -r MT_PORT=$("${VEYRON_BIN}/findunusedport")
- "${VEYRON_BIN}/mounttabled" --address="127.0.0.1:${MT_PORT}" &
-
- # Wait for mounttabled to start up.
- sleep 1
-
- export VEYRON_IDENTITY="${ID_FILE}"
- export NAMESPACE_ROOT="/127.0.0.1:${MT_PORT}"
-
- # Start the store daemon.
- local -r VIEWER_PORT=$("${VEYRON_BIN}/findunusedport")
- "${VEYRON_BIN}/stored" --address=127.0.0.1:0 --db="${DB_DIR}" --viewerPort="${VIEWER_PORT}" &
-
- # Wait for stored to start up.
- sleep 1
-
- # Initialize the store with data and templates.
- "${VEYRON_BIN}/mdb_init" --load-all
-
- if [[ -n "${VIEWER_PORT_FILE}" ]]; then
- echo "${VIEWER_PORT}" > "${VIEWER_PORT_FILE}"
- fi
-
- echo
- echo "Visit http://localhost:${VIEWER_PORT} to browse the store."
- echo "Hit Ctrl-C to kill all running services."
- wait
-}
-
-main "$@"
diff --git a/examples/mdb/schema/init.go b/examples/mdb/schema/init.go
deleted file mode 100644
index 8ed77b7..0000000
--- a/examples/mdb/schema/init.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Package schema defines a schema for a movie rating database. It contains
-// Movies, Actors, Parts, etc.
-//
-// This is designed as a demo application. The target is that each user would
-// have a local copy of the store, and the movie database would be shared
-// through a replication group. User would create new content, movies, reviews,
-// etc. and the content would be merged by synchronization.
-//
-// At the moment, synchronization and queries are not yet implemented, so
-// these features are missing. However, the store provides a basic UI.
-package schema
-
-import (
- "veyron2/vom"
-)
-
-func init() {
- vom.Register(&Dir{})
- vom.Register(&Movie{})
- vom.Register(&Part{})
- vom.Register(&Person{})
- vom.Register(&Review{})
-}
diff --git a/examples/mdb/schema/schema.vdl b/examples/mdb/schema/schema.vdl
deleted file mode 100644
index d90ed86..0000000
--- a/examples/mdb/schema/schema.vdl
+++ /dev/null
@@ -1,48 +0,0 @@
-package schema
-
-import (
- "veyron.io/store/veyron2/storage"
-)
-
-// Dir is used to represent directories.
-type Dir struct{}
-
-// Movie represents a movie.
-type Movie struct {
- Image string // URL
- Title string
- Summary string
- Language string
- // TODO(jyh): Replace these times with IDL types when they are implemented.
- ReleaseDate int64 // ns since the Unix epoch.
- Runtime int64 // ns
- Genre string
- Director storage.ID
- // Subdirectories:
- //
- // Cast/ contains values of type Part.
- // Reviews/ contains values of type Review.
-}
-
-// Part represents the role of an actor.
-type Part struct {
- Actor storage.ID // Person
- Character string
-}
-
-// Review is a movie review.
-type Review struct {
- Rating byte // 1-10.
- Text string
-}
-
-// Person represents a person, in any role, including producers, director,
-// actor, etc.
-type Person struct {
- Image string // URL
- Name string
- BirthDate int64 // ns since the Unix epoch.
- // Subdirectories:
- //
- // Roles/ contains values of type Role.
-}
diff --git a/examples/mdb/schema/schema.vdl.go b/examples/mdb/schema/schema.vdl.go
deleted file mode 100644
index 6867e83..0000000
--- a/examples/mdb/schema/schema.vdl.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: schema.vdl
-
-package schema
-
-import (
- "veyron.io/store/veyron2/storage"
-)
-
-// Dir is used to represent directories.
-type Dir struct {
-}
-
-// Movie represents a movie.
-type Movie struct {
- Image string // URL
- Title string
- Summary string
- Language string
- // TODO(jyh): Replace these times with IDL types when they are implemented.
- ReleaseDate int64 // ns since the Unix epoch.
- Runtime int64 // ns
- Genre string
- Director storage.ID
-}
-
-// Part represents the role of an actor.
-type Part struct {
- Actor storage.ID // Person
- Character string
-}
-
-// Review is a movie review.
-type Review struct {
- Rating byte // 1-10.
- Text string
-}
-
-// Person represents a person, in any role, including producers, director,
-// actor, etc.
-type Person struct {
- Image string // URL
- Name string
- BirthDate int64 // ns since the Unix epoch.
-}
diff --git a/examples/mdb/templates/contents.json b/examples/mdb/templates/contents.json
deleted file mode 100644
index 9d72b6b..0000000
--- a/examples/mdb/templates/contents.json
+++ /dev/null
@@ -1,168 +0,0 @@
-{
- "People": {
- "P1": {
- "Name": "Catherine Deneuve",
- "BirthDate": "22/10/1943",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Catherine_Deneuve_1995.jpg/388px-Catherine_Deneuve_1995.jpg"
- },
- "P2": {
- "Name": "Nino Castelnuovo",
- "BirthDate": "28/10/1936",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/4/4f/Quella_et%C3%A0_maliziosa.png"
- },
- "P3": {
- "Name": "Anne Vernon",
- "BirthDate": "24/1/1925",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/6/6e/Anne_Vernon_1957.jpg"
- },
- "P4": {
- "Name": "Marc Michel",
- "BirthDate": "4/12/1932"
- },
- "P5": {
- "Name": "Leonardo DiCaprio",
- "BirthDate": "11/11/1974",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Leonardo_DiCaprio_%28Berlin_Film_Festival_2010%29_2_%28cropped%29.jpg/711px-Leonardo_DiCaprio_%28Berlin_Film_Festival_2010%29_2_%28cropped%29.jpg"
- },
- "P6": {
- "Name": "Claire Danes",
- "BirthDate": "4/12/1979",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/3/32/Claire_Danes_2012_Shankbone.JPG/479px-Claire_Danes_2012_Shankbone.JPG"
- },
- "P7": {
- "Name": "John Leguizamo",
- "BirthDate": "6/22/1964",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/7/7c/John_Leguizamo_by_Gage_Skidmore.jpg"
- },
- "P8": {
- "Name": "Harold Perrineau",
- "BirthDate": "8/7/1963",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Harold_Perrineau%2C_Jr.jpg/549px-Harold_Perrineau%2C_Jr.jpg"
- },
- "P9": {
- "Name": "Joseph Gordon-Levitt",
- "BirthDate": "17/2/1981",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/Joseph_Gordon-Levitt.jpg/480px-Joseph_Gordon-Levitt.jpg"
- },
- "P10": {
- "Name": "Ellen Page",
- "BirthDate": "21/2/1987",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Ellen_Page_at_TIFF_2009_cropped.jpg/449px-Ellen_Page_at_TIFF_2009_cropped.jpg"
- },
- "P11": {
- "Name": "Michael Caine",
- "BirthDate": "14/3/1933",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Michael_Caine_-_Viennale_2012_a.jpg/400px-Michael_Caine_-_Viennale_2012_a.jpg"
- },
- "P12": {
- "Name": "Jacques Demy",
- "BirthDate": "5/6/1931",
- "Image": "http://upload.wikimedia.org/wikipedia/en/3/3a/Jacques_Demy.jpg"
- },
- "P13": {
- "Name": "Baz Luhrmann",
- "BirthDate": "17/9/1962",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Baz_Luhrmann.jpg/399px-Baz_Luhrmann.jpg"
- },
- "P14": {
- "Name": "Christopher Nolan",
- "BirthDate": "30/7/1970",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/c/c4/Christopher_Nolan%2C_London%2C_2013_%28crop%29.jpg/409px-Christopher_Nolan%2C_London%2C_2013_%28crop%29.jpg"
- },
- "P15": {
- "Name": "Jason Reitman",
- "BirthDate": "19/10/1977",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Jason_Reitman_2013_TIFF.jpg/428px-Jason_Reitman_2013_TIFF.jpg"
- },
- "P16": {
- "Name": "John Lasseter",
- "BirthDate": "12/1/1957",
- "Image": "http://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/JohnLasseterOct2011.jpg/512px-JohnLasseterOct2011.jpg"
- }
- },
-
- "Movies": {
- "M1": {
- "Title": "The Umbrellas of Cherbourg",
- "Image": "http://upload.wikimedia.org/wikipedia/en/3/39/ParapluiePoster.jpg",
- "Summary": "A young girl separated from her lover by war faces a life altering decision.",
- "Language": "French",
- "ReleaseDate": "16/12/1964",
- "Runtime": 91,
- "Genre": "musical",
- "Director": "P12"
- },
- "M2": {
- "Title": "Romeo + Juliet",
- "Image": "http://upload.wikimedia.org/wikipedia/en/b/b4/William_shakespeares_romeo_and_juliet_movie_poster.jpg",
- "Summary": "Shakespeare's famous play is updated to the hip modern suburb of Verona still retaining its original dialogue.",
- "Language": "English",
- "ReleaseDate": "28/2/1997",
- "Runtime": 120,
- "Genre": "drama",
- "Director": "P13"
- },
- "M3": {
- "Title": "Inception",
- "Image": "http://upload.wikimedia.org/wikipedia/en/7/7f/Inception_ver3.jpg",
- "Summary": "A skilled extractor is offered a chance to regain his old life as payment for a task considered to be impossible.",
- "Language": "English",
- "ReleaseDate": "16/6/2010",
- "Runtime": 148,
- "Genre": "action",
- "Director": "P14"
- },
- "M4": {
- "Title": "Juno",
- "Image": "http://upload.wikimedia.org/wikipedia/en/e/ec/Junoposter2007.jpg",
- "Summary": "Faced with an unplanned pregnancy, an offbeat young woman makes an unusual decision regarding her unborn child.",
- "Language": "English",
- "ReleaseDate": "25/12/2007",
- "Runtime": 96,
- "Genre": "comedy",
- "Director": "P15"
- },
- "M5": {
- "Title": "Cars 2",
- "Image": "http://upload.wikimedia.org/wikipedia/en/7/7f/Cars_2_Poster.jpg",
- "Summary": "Star race car Lightning McQueen and his pal Mater head overseas to compete in the World Grand Prix race. But the road to the championship becomes rocky as Mater gets caught up in an intriguing adventure of his own: international espionage.",
- "Language": "English",
- "ReleaseDate": "12/6/2011",
- "Runtime": 0,
- "Genre": "animation",
- "Director": "P16"
- }
- },
-
- "Parts": {
- "p1": { "Movie": "M1", "Actor": "P1", "Character": "Geneviève Emery" },
- "p2": { "Movie": "M1", "Actor": "P2", "Character": "Guy Foucher" },
- "p3": { "Movie": "M1", "Actor": "P3", "Character": "Madame Emery" },
- "p4": { "Movie": "M1", "Actor": "P4", "Character": "Roland Cassard" },
- "p5": { "Movie": "M2", "Actor": "P5", "Character": "Romeo" },
- "p6": { "Movie": "M2", "Actor": "P6", "Character": "Juliet" },
- "p7": { "Movie": "M2", "Actor": "P7", "Character": "Tybalt" },
- "p8": { "Movie": "M2", "Actor": "P8", "Character": "Mercutio" },
- "p9": { "Movie": "M3", "Actor": "P5", "Character": "Cobb" },
- "p10": { "Movie": "M3", "Actor": "P9", "Character": "Arthur" },
- "p11": { "Movie": "M3", "Actor": "P10", "Character": "Ariadne" },
- "p12": { "Movie": "M3", "Actor": "P11", "Character": "Miles" },
- "p13": { "Movie": "M4", "Actor": "P10", "Character": "Juno" },
- "p14": { "Movie": "M5", "Actor": "P11", "Character": "Finn McMissile" }
- },
-
- "Reviews": {
- "r1": { "Movie": "M1", "Rating": 10, "Text": "It makes my heart ache just to think about it..." },
- "r2": { "Movie": "M1", "Rating": 10, "Text": "I Will Wait for You" },
- "r3": { "Movie": "M1", "Rating": 10, "Text": "Toto, I've a feeling we're not in Kansas anymore." },
- "r4": { "Movie": "M2", "Rating": 9, "Text": "Moderized Without Losing the Shakespeare" },
- "r5": { "Movie": "M2", "Rating": 1, "Text": "Oh Please!! The 1968 version is a whole lot better than this crap!" },
- "r6": { "Movie": "M2", "Rating": 8, "Text": "Very surprisingly very good" },
- "r7": { "Movie": "M3", "Rating": 9, "Text": "Matrix but in dreamworld? Nah." },
- "r8": { "Movie": "M3", "Rating": 10, "Text": "Insanely Brilliant ! Nolan has outdone himself !!" },
- "r9": { "Movie": "M3", "Rating": 1, "Text": "an intellectual challenging movie for people, who can't speak in relative clauses." },
- "r10": { "Movie": "M4", "Rating": 9, "Text": "Every good thing you've heard and more" },
- "r11": { "Movie": "M5", "Rating": 8, "Text": "An action-filled fun change of pace" },
- "r12": { "Movie": "M5", "Rating": 3, "Text": "Such a disappointment" }
- }
-}
diff --git a/examples/mdb/templates/css/movie.css b/examples/mdb/templates/css/movie.css
deleted file mode 100644
index dff45e5..0000000
--- a/examples/mdb/templates/css/movie.css
+++ /dev/null
@@ -1,83 +0,0 @@
-body {
- font-family: sans-serif;
-}
-.title {
- font-weight: bolder;
- font-size: 5em;
- font-family: Gill Sans Extrabold, sans-serif;
- font-style: oblique;
-}
-.genre {
- font-family: sans-serif;
- font-style: oblique;
-}
-.debug {
- font-style: oblique;
- color: gray;
-}
-.castbox {
- border: 1px solid #bbb;
- border-radius: 10px;
- background-color: #fbfbfb;
- width: 95%;
-}
-.cast {
- border-collapse: collapse;
- background-color: white;
- margin: 5px;
- width: 98%;
-}
-.cast tr {
- margin: 5px;
- height: 32px;
-}
-.cast tr:nth-child(even) {
- background-color: #f6f6f5;
-}
-.cast tr:nth-child(odd) {
- background-color: #f2f2f8;
-}
-.castchar {
- width: 200px;
-}
-.reviewbox {
- border: 1px solid #bbb;
- border-radius: 4px;
- background-color: #fbfbfb;
- margin: 5px;
- width: 95%;
-}
-.rating {
- font-weight: bolder;
-}
-.reviewtext {
-}
-.moviesbox {
- border: 1px solid #bbb;
- border-radius: 10px;
- background-color: #fbfbfb;
- width: 95%;
-}
-.moviestable {
- border-collapse: collapse;
- background-color: white;
- margin: 5px;
- width: 98%;
-}
-.moviestable tr {
- margin: 5px;
- height: 32px;
-}
-.moviestable tr:nth-child(even) {
- background-color: #f6f6f5;
-}
-.moviestable tr:nth-child(odd) {
- background-color: #f2f2f8;
-}
-.moviesentry {
-}
-.peoplebox {
- background-color: #fbfbfb;
- margin: 5px;
- width: 95%;
-}
diff --git a/examples/mdb/templates/veyron/examples/mdb/schema/Dir.tmpl b/examples/mdb/templates/veyron/examples/mdb/schema/Dir.tmpl
deleted file mode 100644
index 51bec6b..0000000
--- a/examples/mdb/templates/veyron/examples/mdb/schema/Dir.tmpl
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>{{.Name}}</title>
- <link rel="stylesheet" href="/css/movie.css">
- </head>
- <body>
- <p><a href="/">Home</a></p>
- {{$value := .}}
-
- <!-- Movie listing -->
- {{with $value.Glob "movies/*"}}
- <div class="moviesbox">
- <h2>Movies</h2>
- <table class="moviestable">
- {{range .}}
- <tr>
- <td class="movieentry"><a href="{{.}}">{{$value.Base .}}</a>
- </tr>
- {{end}}
- </table>
- </div>
- {{end}}
-
- <!-- People listing -->
- {{with $value.Glob "people/*"}}
- <h2>People</h2>
- {{range .}}
- <div class="peoplebox">
- <p><a href="{{.}}">{{$value.Base .}}</a></p>
- </div>
- {{end}}
- {{end}}
-
- <!-- Debugging -->
- <span class="debug">{{.Name}} <a href="?raw">Raw</a></span>
- </body>
-</html>
diff --git a/examples/mdb/templates/veyron/examples/mdb/schema/Movie.tmpl b/examples/mdb/templates/veyron/examples/mdb/schema/Movie.tmpl
deleted file mode 100644
index 7bc80e7..0000000
--- a/examples/mdb/templates/veyron/examples/mdb/schema/Movie.tmpl
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- {{$title := .Value.Title}}
- {{$value := .}}
- {{$prefix := $value.Join "/movies/" $title}}
- <title>{{$title}}</title>
- <link rel="stylesheet" href="/css/movie.css">
- </head>
- <body>
- <p><a href="/">Home</a></p>
- {{$releaseDate := $value.Date .Value.ReleaseDate}}
- <table>
- <tr>
- <td valign="top">
- <img src="{{.Value.Image}}" align="bottom">
- </td>
- <td valign="top">
- <div>
- <span class="title">{{$title}}</span>
- <span class="date">({{$releaseDate.Year}})</span>
- <span class="genre">{{.Value.Genre}}</span>
- <p>
- {{$director := $value.Get "Director"}}
- {{$path := $value.Join $value.Name "Director"}}
- Director: <a href="{{$path}}">{{$director.Name}}</a>
- </p>
- </div>
- </td>
- </tr>
- </table>
-
- <!-- Table to display the cast -->
- {{with $value.Glob "Cast/*"}}
- <div class="castbox">
- <h2>Cast</h2>
- <table class="cast">
- {{range .}}
- <tr> <!-- . = /Cast/pXX -->
- {{$part := $value.Get .}}
- {{$actorRelativePath := $value.Join . "Actor"}}
- {{$actor := $value.Get $actorRelativePath}}
- {{$path := $value.Join "/people/" $actor.Name}}
- <td class="castactor">
- <a href="{{$path}}">{{$actor.Name}}</a>
- </td>
- <td class="castchar">{{$part.Character}}</td>
- </tr>
- {{end}}
- </table>
- </div>
- {{end}}
-
- <!-- Reviews -->
- {{with $value.Glob "Reviews/*"}}
- <h2>Reviews</h2>
- {{range .}}
- {{$review := $value.Get .}}
- <div class="reviewbox">
- <p><span class="rating">Rating: {{$review.Rating}}/10</span></p>
- <p><span class="reviewtext">{{$review.Text}}</span></p>
- </div>
- {{end}}
- {{end}}
-
- <!-- Debugging -->
- <span class="debug">{{.Name}} <a href="?raw">Raw</a></span>
- </body>
-</html>
diff --git a/examples/mdb/templates/veyron/examples/mdb/schema/Person.tmpl b/examples/mdb/templates/veyron/examples/mdb/schema/Person.tmpl
deleted file mode 100644
index b1bd7ab..0000000
--- a/examples/mdb/templates/veyron/examples/mdb/schema/Person.tmpl
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>{{.Value.Name}}</title>
- <link rel="stylesheet" href="/css/movie.css">
- </head>
- <body>
- <p><a href="/">Home</a></p>
- {{$value := .}}
- <table>
- <tr>
- <td valign="top">
- <img src="{{.Value.Image}}" align="bottom">
- </td>
- <td valign="top">
- <div>
- <span class="title">{{.Value.Name}}</span>
- </div>
- </td>
- </tr>
- </table>
-
- <p>
- {{$date := $value.Date .Value.BirthDate}}
- Born:
- <span class="date">
- {{$date.Month}} {{$date.Day}}, {{$date.Year}}
- </span>
- </p>
-
- <!-- Debugging -->
- <span class="debug">{{.Name}} <a href="?raw">Raw</a></span>
- </body>
-</html>
diff --git a/examples/mdb/test.sh b/examples/mdb/test.sh
deleted file mode 100755
index 459fafd..0000000
--- a/examples/mdb/test.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-
-# Tests this example.
-#
-# Builds binaries, starts up services, waits a few seconds, then checks that the
-# store browser responds with valid data.
-
-source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
-
-main() {
- # TODO(kash): This test is disabled while we redo the store API.
- shell_test::pass
-
- cd "${REPO_ROOT}/go/src/veyron/examples/mdb"
- make build &>/dev/null || shell_test::fail "line ${LINENO}: failed to build"
- local -r VIEWER_PORT_FILE="${TMPDIR}/viewer_port.txt"
- ./run.sh "${VIEWER_PORT_FILE}" &>/dev/null &
-
- sleep 5 # Wait for services to warm up.
-
- if [ ! -f "${VIEWER_PORT_FILE}" ]; then
- shell_test::fail "line ${LINENO}: failed to get viewer url"
- fi
- local -r VIEWER_PORT=$(cat "${VIEWER_PORT_FILE}")
-
- local -r HTML_FILE="${TMPDIR}/index.html"
- local -r URL="http://127.0.0.1:${VIEWER_PORT}"
- curl 2>/dev/null "${URL}" -o "${HTML_FILE}" || shell_test::fail "line ${LINENO}: failed to fetch ${URL}"
-
- if grep -q "moviesbox" "${HTML_FILE}"; then
- shell_test::pass
- else
- cat "${HTML_FILE}"
- shell_test::fail "line ${LINENO}: fetched page does not meet expectations"
- fi
-}
-
-main "$@"
diff --git a/examples/netconfigwatcher/main.go b/examples/netconfigwatcher/main.go
deleted file mode 100644
index 5716d5d..0000000
--- a/examples/netconfigwatcher/main.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package main
-
-import (
- "fmt"
- "log"
-
- "veyron/lib/netconfig"
-)
-
-func main() {
- w, err := netconfig.NewNetConfigWatcher()
- if err != nil {
- log.Fatalf("oops: %s", err)
- }
- fmt.Println("Do something to your network. You should see one or more dings.")
- for {
- <-w.Channel()
- fmt.Println("ding")
- }
-}
diff --git a/examples/pipetobrowser/.gitignore b/examples/pipetobrowser/.gitignore
deleted file mode 100644
index 4cf7941..0000000
--- a/examples/pipetobrowser/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-browser/index.html
-browser/build.js
-browser/third-party
-node_modules
\ No newline at end of file
diff --git a/examples/pipetobrowser/Makefile b/examples/pipetobrowser/Makefile
deleted file mode 100644
index 0953b87..0000000
--- a/examples/pipetobrowser/Makefile
+++ /dev/null
@@ -1,65 +0,0 @@
-PATH:=$(VEYRON_ROOT)/environment/cout/node/bin:$(PATH)
-PATH:=node_modules/.bin:../node_modules/.bin:$(PATH)
-
-VEYRON_BUILD_SCRIPT=$(VEYRON_ROOT)/veyron/scripts/build/go
-
-# All JS files except build.js and third party
-JS_FILES = $(shell find browser -name "*.js" -a -not -name "build.js" -a -not -path "*third-party*")
-# All HTML/CSS files except index.html and third party
-HTML_FILES = $(shell find browser -name "*.css" -a -not -path "*third-party*" -o -name "*.html" -a -not -name "index.html" -a -not -path "*third-party*")
-
-# Builds everything
-all: node_modules browser/third-party browser/third-party/veyron browser/build.js browser/index.html $(VEYRON_ROOT)/veyron/go/bin
-
-# Build p2b cli binary
-$(VEYRON_ROOT)/veyron/go/bin: p2b/main.go
- $(VEYRON_BUILD_SCRIPT) install veyron/...
-
-# Install what we need from NPM, tools such as jspm, serve, etc...
-node_modules: package.json
- npm prune
- npm install
- touch node_modules
- export
-
-# Build and copies Veyron from local source
-browser/third-party/veyron: node_modules
- cp -rf $</veyron/dist/ $@
-
-# Install JSPM and Bower packages as listed in browser/package.json from JSPM and browser/bower.json from bower
-browser/third-party: browser/package.json browser/bower.json
- cd browser; \
- jspm install -h; \
- bower prune; \
- bower install
- touch browser/third-party
-
-# Bundle whole app and third-party JavaScript into a single build.js
-browser/build.js: $(JS_FILES)
- cd browser; \
- jspm setmode local; \
- jspm bundle app build.js
- touch browser/third-party
-
-# Bundle all app web components and third-party web components into a single index.html
-browser/index.html: $(HTML_FILES)
- cd browser; \
- vulcanize -o index.html app.html
-
-# Serve
-start:
- ./services.sh
-
-# Continuously watch for changes to .js, .html or .css files.
-# Rebundle the appropriate file (build.js and/or index.html) when local files change
-watch:
- watch -n 1 make
-
-# Clean all build artifacts
-clean:
- rm -rf browser/third-party
- rm -rf node_modules
- rm -f browser/index.html
- rm -f browser/build.js
-
-.PHONY: start clean watch
diff --git a/examples/pipetobrowser/README.md b/examples/pipetobrowser/README.md
deleted file mode 100644
index d8a9148..0000000
--- a/examples/pipetobrowser/README.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# Pipe to Browser
-P2B allows one to pipe anything from shell console to the browser. Data being piped to the browser then is displayed in a graphical and formatted way by a "viewer" Viewers are pluggable pieces of code that know how to handle and display a stream of data.
-
-For example one can do:
-
-``
-echo "Hi!" | p2b google/p2b/jane/console
-``
-
-or
-
-``
-cat cat.jpg | p2b -binary google/p2b/jane/image
-``
-
-where **google/p2b/jane** is the Object name where p2b service is running in the browser. The suffix **console** or **image** specifies what viewer should be used to display the data.
-
-Please see the help page inside the P2B application for detailed tutorials.
-
-## Building and Running
-To build
-``
-make
-``
-To run
-``
-make start #Starts a web server at 8080
-``
-and then navigate to http://localhost:8080
-
-To stop simply Ctrl-C the console that started it
-
-To clean
-``
-make clean
-``
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/.bowerrc b/examples/pipetobrowser/browser/.bowerrc
deleted file mode 100644
index 779273b..0000000
--- a/examples/pipetobrowser/browser/.bowerrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "directory" : "third-party"
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/actions/add-pipe-viewer.js b/examples/pipetobrowser/browser/actions/add-pipe-viewer.js
deleted file mode 100644
index a284731..0000000
--- a/examples/pipetobrowser/browser/actions/add-pipe-viewer.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * AddPipeViewer action can be used to add a new viewer to the pipes view
- * this action can be run at anytime and user can be on any view and this action
- * will still work.
- * Depending on user preferences, user might be presented with a confirmation
- * dialog to accept seeing the incoming pipe.
- * @fileoverview
- */
-
-import { Logger } from 'libs/logs/logger'
-import { register, trigger } from 'libs/mvc/actions'
-
-import { get as getPipeViewer } from 'pipe-viewers/manager'
-
-import { displayError } from 'actions/display-error'
-import { navigatePipesPage } from 'actions/navigate-pipes-page'
-import { redirectPipe } from 'actions/redirect-pipe'
-
-import { LoadingView } from 'views/loading/view'
-
-import { pipesViewInstance } from 'runtime/context'
-
-var log = new Logger('actions/add-pipe-viewer');
-var ACTION_NAME = 'addPipeViewer';
-var pipesPerNameCounter = {};
-
-/*
- * Registers the add pipe viewer action
- */
-export function registerAddPipeViewerAction() {
- register(ACTION_NAME, actionHandler);
-}
-
-/*
- * Triggers the add pipe viewer action
- */
-export function addPipeViewer(name, stream) {
- return trigger(ACTION_NAME, name, stream);
-}
-
-/*
- * Handles the addPipeViewer action.
- * @param {string} name Name of the Pipe Viewer that is requested to play the stream.
- * @param {Veyron.Stream} stream Stream of bytes from the p2b client.
- *
- * @private
- */
-function actionHandler(name, stream) {
- log.debug('addPipeViewer action triggered');
-
- // Book keeping of number of pipe-viewers per name, we use this to generate
- // display names and keys like image #3
- var count = (pipesPerNameCounter[name] || 0) + 1;
- pipesPerNameCounter[name] = count;
- var tabKey = name + count;
- var tabName = 'Loading...';
-
- // Get the plugin that can render the stream, ask it to play it and display
- // the element returned by the pipeViewer.
- getPipeViewer(name).then((pipeViewer) => {
- tabName = pipeViewer.name + ' #' + count
- return pipeViewer.play(stream);
- }).then((pipeViewerView) => {
- // replace the loading view with the actual viewerView
- pipesViewInstance.replaceTabView(tabKey, tabName, pipeViewerView);
- }).catch((e) => { displayError(e); });
-
- // Add a new tab and show a loading indicator for now,
- // then replace the loading view with the actual viewer when ready
- // close the stream when tab closes
- var loadingView = new LoadingView();
- pipesViewInstance.addTab(tabKey, tabName, loadingView, () => {
- stream.end();
- });
-
- // Add the redirect stream action
- var icon = 'hardware:cast';
- pipesViewInstance.addToolbarAction(tabKey, icon, () => {
- redirectPipe(stream, name);
- });
-
- // Take the user to the pipes view.
- navigatePipesPage();
-}
diff --git a/examples/pipetobrowser/browser/actions/display-error.js b/examples/pipetobrowser/browser/actions/display-error.js
deleted file mode 100644
index bc2695b..0000000
--- a/examples/pipetobrowser/browser/actions/display-error.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Error action displays the error page displaying the given error
- * @fileoverview
- */
-
-import { Logger } from 'libs/logs/logger'
-import { register, trigger } from 'libs/mvc/actions'
-
-import { ErrorView } from 'views/error/view'
-
-import { page } from 'runtime/context'
-
-var log = new Logger('actions/display-error');
-var ACTION_NAME = 'error';
-
-/*
- * Registers the error action
- */
-export function registerDisplayErrorAction() {
- register(ACTION_NAME, actionHandler);
-}
-
-/*
- * Triggers the error action
- */
-export function displayError(err) {
- return trigger(ACTION_NAME, err);
-}
-
-/*
- * Handles the error action.
- *
- * @private
- */
-function actionHandler(err) {
- log.debug('error action triggered');
-
- // Create an error view
- var errorView = new ErrorView(err);
-
- // Display the error view in Home sub-page area
- page.setSubPageView('home', errorView);
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/actions/navigate-help.js b/examples/pipetobrowser/browser/actions/navigate-help.js
deleted file mode 100644
index 01f2117..0000000
--- a/examples/pipetobrowser/browser/actions/navigate-help.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Navigates to help page
- * @fileoverview
- */
-import { Logger } from 'libs/logs/logger'
-import { register, trigger } from 'libs/mvc/actions'
-
-import { state as publishState } from 'services/pipe-to-browser-server'
-
-import { page } from 'runtime/context'
-
-import { HelpView } from 'views/help/view'
-
-var log = new Logger('actions/navigate-help');
-var ACTION_NAME = 'help';
-
-/*
- * Registers the action
- */
-export function registerHelpAction() {
- register(ACTION_NAME, actionHandler);
-}
-
-/*
- * Triggers the action
- */
-export function navigateHelp() {
- return trigger(ACTION_NAME);
-}
-
-/*
- * Handles the action.
- *
- * @private
- */
-function actionHandler() {
- log.debug('navigate help triggered');
-
- // create a help view
- var helpView = new HelpView(publishState);
-
- page.setSubPageView('help', helpView);
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/actions/navigate-home-page.js b/examples/pipetobrowser/browser/actions/navigate-home-page.js
deleted file mode 100644
index 888e5d1..0000000
--- a/examples/pipetobrowser/browser/actions/navigate-home-page.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Home action displays the Home page. Home could be status or publish view
- * depending on the state of the P2B service.
- * @fileoverview
- */
-
-import { Logger } from 'libs/logs/logger'
-import { register, trigger } from 'libs/mvc/actions'
-
-import { publish, stopPublishing, state as publishState } from 'services/pipe-to-browser-server'
-
-import { displayError } from 'actions/display-error'
-import { addPipeViewer } from 'actions/add-pipe-viewer'
-
-import { PublishView } from 'views/publish/view'
-import { StatusView } from 'views/status/view'
-
-import { page } from 'runtime/context'
-
-var log = new Logger('actions/navigate-home-page');
-var ACTION_NAME = 'home';
-
-/*
- * Registers the home action
- */
-export function registerNavigateHomePageAction() {
- register(ACTION_NAME, actionHandler);
-}
-
-/*
- * Triggers the home action
- */
-export function navigateHomePage() {
- return trigger(ACTION_NAME);
-}
-
-/*
- * Handles the home action.
- *
- * @private
- */
-function actionHandler() {
- log.debug('home action triggered');
-
- var mainView;
-
- // Show status view if already published, otherwise show publish view
- if (publishState.published) {
- showStatusView();
- } else {
- showPublishView();
- }
-}
-
-/*
- * Displays the Status view
- *
- * @private
- */
-function showStatusView() {
- // Create a status view and bind (dynamic) publish state with the view
- var statusView = new StatusView(publishState);
-
- // Stop when user tells us to stop the service
- statusView.onStopAction(() => {
- stopPublishing().then(function() {
- navigateHomePage();
- }).catch((e) => { displayError(e); });
- });
-
- // Display the status view in main content area and select the sidebar item
- page.title = 'Status';
- page.setSubPageView('home', statusView);
-}
-
-/*
- * Displays the Publish view
- *
- * @private
- */
-function showPublishView() {
- // Create a publish view
- var publishView = new PublishView();
-
- // Publish p2b when user tells us to do so and then show status page.
- publishView.onPublishAction((publishName) => {
- publish(publishName, pipeRequestHandler).then(function() {
- showStatusView();
- }).catch((e) => { displayError(e); });
- });
-
- // Display the publish view in main content area and select the sidebar item
- page.title = 'Publish';
- page.setSubPageView('home', publishView);
-}
-
-/*
- * pipeRequestHandler is called by the p2b service whenever a new request comes in.
- * We simply delegate to the addPipeViewer action.
- * @param {string} name Name of the Pipe Viewer that is requested to play the stream.
- * @param {Veyron.Stream} stream Stream of bytes from the p2b client.
- *
- * @private
- */
-function pipeRequestHandler(name, stream) {
- return addPipeViewer(name, stream);
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/actions/navigate-neighborhood.js b/examples/pipetobrowser/browser/actions/navigate-neighborhood.js
deleted file mode 100644
index fc8c979..0000000
--- a/examples/pipetobrowser/browser/actions/navigate-neighborhood.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Navigates to neighborhood page displaying list of P2B names that are online
- * @fileoverview
- */
-
-import { Logger } from 'libs/logs/logger'
-import { register, trigger } from 'libs/mvc/actions'
-
-import { displayError } from 'actions/display-error'
-import { page } from 'runtime/context'
-
-import { NeighborhoodView } from 'views/neighborhood/view'
-import { getAll as getAllPublishedP2BNames } from 'services/pipe-to-browser-namespace'
-
-var log = new Logger('actions/navigate-neighborhood');
-var ACTION_NAME = 'neighborhood';
-
-/*
- * Registers the action
- */
-export function registerNavigateNeigbourhoodAction() {
- register(ACTION_NAME, actionHandler);
-}
-
-/*
- * Triggers the action
- */
-export function navigateNeigbourhood() {
- return trigger(ACTION_NAME);
-}
-
-/*
- * Handles the action.
- *
- * @private
- */
-function actionHandler() {
- log.debug('navigate neighborhood triggered');
-
- // create an neighborhood view
- var neighborhoodView = new NeighborhoodView();
-
- // get all the online names and set it on the view
- getAllPublishedP2BNames().then((allNames) => {
- neighborhoodView.existingNames = allNames;
- }).catch((e) => { displayError(e); });
-
- page.setSubPageView('neighborhood', neighborhoodView);
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/actions/navigate-pipes-page.js b/examples/pipetobrowser/browser/actions/navigate-pipes-page.js
deleted file mode 100644
index 4d8d3c3..0000000
--- a/examples/pipetobrowser/browser/actions/navigate-pipes-page.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Pipes action displays the Pipes page. It is normally triggered by clicking
- * the Pipes navigation item in the side bar
- * @fileoverview
- */
-
-import { Logger } from 'libs/logs/logger'
-import { register, trigger } from 'libs/mvc/actions'
-
-import { page, pipesViewInstance } from 'runtime/context'
-
-var log = new Logger('actions/navigate-pipes-page');
-var ACTION_NAME = 'pipes';
-
-/*
- * Registers the pipes action
- */
-export function registerNavigatePipesPageAction() {
- register(ACTION_NAME, actionHandler);
-}
-
-/*
- * Triggers the pipes action
- */
-export function navigatePipesPage(err) {
- return trigger(ACTION_NAME, err);
-}
-
-/*
- * Handles the pipes action.
- *
- * @private
- */
-function actionHandler() {
- log.debug('pipes action triggered');
-
- // display the singleton pipesViewInstance main content area
- page.title = 'Pipes';
- page.setSubPageView('pipes', pipesViewInstance);
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/actions/redirect-pipe.js b/examples/pipetobrowser/browser/actions/redirect-pipe.js
deleted file mode 100644
index 6bcb93b..0000000
--- a/examples/pipetobrowser/browser/actions/redirect-pipe.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Redirects a stream to another veyron name. It prompts the user to pick
- * a Veyron name before redirecting and allows the user to chose between
- * redirecting all the data or just new incoming data.
- * @fileoverview
- */
-import { Logger } from 'libs/logs/logger'
-import { register, trigger } from 'libs/mvc/actions'
-
-import { page } from 'runtime/context'
-
-import { RedirectPipeDialogView } from 'views/redirect-pipe-dialog/view'
-import { pipe } from 'services/pipe-to-browser-client'
-import { getAll as getAllPublishedP2BNames } from 'services/pipe-to-browser-namespace'
-
-var log = new Logger('actions/redirect-pipe');
-var ACTION_NAME = 'redirect-pipe';
-
-/*
- * Registers the redirect pipe action
- */
-export function registerRedirectPipeAction() {
- register(ACTION_NAME, actionHandler);
-}
-
-/*
- * Triggers the redirect pipe action
- * @param {stream} stream Stream object to redirect
- * @param {string} currentPluginName name of the current plugin
- */
-export function redirectPipe(stream, currentPluginName) {
- return trigger(ACTION_NAME, stream, currentPluginName);
-}
-
-/*
- * Handles the redirect pipe action.
- *
- * @private
- */
-function actionHandler(stream, currentPluginName) {
- log.debug('redirect pipe action triggered');
-
- // display a dialog asking user where to redirect and whether to redirect
- // all the data or just new data.
- var dialog = new RedirectPipeDialogView();
- dialog.open();
-
- // if user decides to redirect, copy the stream and pipe it.
- dialog.onRedirectAction((name, newDataOnly) => {
- var copyStream = stream.copier.copy(newDataOnly);
-
- pipe(name, copyStream).then(() => {
- page.showToast('Redirected successfully to ' + name);
- }).catch((e) => {
- page.showToast('FAILED to redirect to ' + name + '. Please see console for error details.');
- log.debug('FAILED to redirect to', name, e);
- });
- });
-
- // also get the list of all existing P2B names in the namespace and supply it to the dialog
- getAllPublishedP2BNames().then((allNames) => {
- // append current plugin name to the veyron names for better UX
- dialog.existingNames = allNames.map((n) => {
- return n + '/' + currentPluginName;
- });
- }).catch((e) => {
- log.debug('getAllPublishedP2BNames failed', e);
- });
-}
diff --git a/examples/pipetobrowser/browser/app.html b/examples/pipetobrowser/browser/app.html
deleted file mode 100644
index d4d7597..0000000
--- a/examples/pipetobrowser/browser/app.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
- <meta name="mobile-web-app-capable" content="yes">
- <meta name="apple-mobile-web-app-capable" content="yes">
- <meta name="description" content="Pipe To Browser (p2b) is a utility built with veyron technology that allows piping of stdout and std from console into local or remote browser windows. Different plugins exist to format the incoming data and display them in an appropriate and interactive format.">
- <title>Pipe To Browser - because life is too short to stare at unformatted stdout text, and is hard enough already not to have a spell-checker for stdin</title>
-
- <script src="third-party/platform/platform.js"></script>
- <!-- TODO(aghassemi) use CJS version of Veyron and provide an ES6 shim -->
- <script src="third-party/veyron/veyron.js"></script>
-
- <script src="third-party/traceur-runtime@0.0.49.js"></script>
- <script src="third-party/system@0.6.js"></script>
- <script src="config.js"></script>
- <script src="shame.js"></script>
- <script src="build.js"></script>
-
- <link rel="import" href="views/page/component.html"/>
-
- <style type="text/css">
- body {
- font-family: 'Roboto', sans-serif;
- color: rgba(0,0,0,0.87);
- }
- </style>
-</head>
-<body>
-
-
- <script>
- window.addEventListener('polymer-ready', function(e) {
- System.import('app').then(function(app) {
- app.start();
- }).catch(function(e) {
- console.error(e);
- });
- });
- </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/app.js b/examples/pipetobrowser/browser/app.js
deleted file mode 100644
index 9718f47..0000000
--- a/examples/pipetobrowser/browser/app.js
+++ /dev/null
@@ -1,84 +0,0 @@
-import { Logger } from 'libs/logs/logger'
-
-import { registerNavigateHomePageAction, navigateHomePage } from 'actions/navigate-home-page'
-import { registerDisplayErrorAction } from 'actions/display-error'
-import { registerAddPipeViewerAction } from 'actions/add-pipe-viewer'
-import { registerNavigatePipesPageAction, navigatePipesPage } from 'actions/navigate-pipes-page'
-import { registerNavigateNeigbourhoodAction, navigateNeigbourhood } from 'actions/navigate-neighborhood'
-import { registerHelpAction, navigateHelp } from 'actions/navigate-help'
-import { registerRedirectPipeAction } from 'actions/redirect-pipe'
-
-import { SubPageItem } from 'views/page/view'
-
-import { page } from 'runtime/context'
-
-var log = new Logger('app');
-
-export function start() {
- log.debug('start called');
-
- // Initialize a new page, sets up toolbar and action bar for the app
- initPageView();
-
- // Register the action handlers for the application
- registerActions();
-
- // Start by triggering the home action
- navigateHomePage();
-}
-
-/*
- * Registers the action handlers for the application.
- * Actions are cohesive pieces of functionality that can be triggered from
- * any other action in a decoupled way by just using the action name.
- *
- * @private
- */
-function registerActions() {
-
- log.debug('registering actions');
-
- registerNavigateHomePageAction();
- registerDisplayErrorAction();
- registerAddPipeViewerAction();
- registerNavigatePipesPageAction();
- registerNavigateNeigbourhoodAction();
- registerRedirectPipeAction();
- registerHelpAction();
-}
-
-/*
- * Constructs a new page, sets up toolbar and action bar for the app
- *
- * @private
- */
-function initPageView() {
-
- // Home, Pipes and Help are top level sub-pages
- var homeSubPageItem = new SubPageItem('home');
- homeSubPageItem.name = 'Home';
- homeSubPageItem.icon = 'home';
- homeSubPageItem.onActivate = navigateHomePage;
- page.subPages.push(homeSubPageItem);
-
- var pipesSubPageItem = new SubPageItem('pipes');
- pipesSubPageItem.name = 'Pipes';
- pipesSubPageItem.icon = 'arrow-forward';
- pipesSubPageItem.onActivate = navigatePipesPage;
- page.subPages.push(pipesSubPageItem);
-
- var neighborhoodSubPageItem = new SubPageItem('neighborhood');
- neighborhoodSubPageItem.name = 'Neighborhood';
- neighborhoodSubPageItem.icon = 'social:circles-extended';
- neighborhoodSubPageItem.onActivate = navigateNeigbourhood;
- page.subPages.push(neighborhoodSubPageItem);
-
- var helpSubPageItem = new SubPageItem('help');
- helpSubPageItem.name = 'Help';
- helpSubPageItem.icon = 'help';
- helpSubPageItem.onActivate = navigateHelp;
-
- page.subPages.push(helpSubPageItem);
-
- document.body.appendChild(page.element);
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/bower.json b/examples/pipetobrowser/browser/bower.json
deleted file mode 100644
index 0217621..0000000
--- a/examples/pipetobrowser/browser/bower.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "name": "pipe-to-browser",
- "version": "0.0.1",
- "dependencies": {
- "polymer": "Polymer/polymer#~0.3.4",
- "core-elements": "Polymer/core-elements#~0.3.4",
- "paper-elements": "Polymer/paper-elements#~0.3.4"
- }
-}
diff --git a/examples/pipetobrowser/browser/config.js b/examples/pipetobrowser/browser/config.js
deleted file mode 100644
index 4206c8a..0000000
--- a/examples/pipetobrowser/browser/config.js
+++ /dev/null
@@ -1,87 +0,0 @@
-System.config({
- "paths": {
- "*": "*.js",
- "pipe-viewer": "pipe-viewers/pipe-viewer.js",
- "pipe-viewer-delegation": "pipe-viewers/pipe-viewer-delegation.js",
- "view": "libs/mvc/view.js",
- "logger": "libs/logs/logger.js",
- "stream-helpers": "libs/utils/stream-helpers.js",
- "web-component-loader": "libs/utils/web-component-loader.js",
- "formatting": "libs/utils/formatting.js",
- "npm:*": "third-party/npm/*.js",
- "github:*": "third-party/github/*.js"
- }
-});
-
-System.config({
- "map": {
- "npm:humanize": "npm:humanize@^0.0.9",
- "npm:event-stream": "npm:event-stream@^3.1.5",
- "nodelibs": "github:jspm/nodelibs@master",
- "npm:event-stream@3.1.5": {
- "from": "npm:from@0",
- "map-stream": "npm:map-stream@0.1",
- "pause-stream": "npm:pause-stream@0.0.11",
- "duplexer": "npm:duplexer@^0.1.1",
- "through": "npm:through@^2.3.1",
- "split": "npm:split@0.2",
- "stream-combiner": "npm:stream-combiner@^0.0.4"
- },
- "npm:humanize@0.0.9": {},
- "npm:from@0.1.3": {},
- "npm:stream-combiner@0.0.4": {
- "duplexer": "npm:duplexer@^0.1.1"
- },
- "npm:duplexer@0.1.1": {},
- "npm:map-stream@0.1.0": {},
- "npm:pause-stream@0.0.11": {
- "through": "npm:through@2.3"
- },
- "npm:split@0.2.10": {
- "through": "npm:through@2"
- },
- "npm:through@2.3.4": {},
- "github:jspm/nodelibs@0.0.2": {
- "ieee754": "npm:ieee754@^1.1.1",
- "base64-js": "npm:base64-js@^0.0.4",
- "Base64": "npm:Base64@0.2",
- "inherits": "npm:inherits@^2.0.1",
- "json": "github:systemjs/plugin-json@master"
- },
- "npm:base64-js@0.0.4": {},
- "npm:ieee754@1.1.3": {},
- "npm:Base64@0.2.1": {},
- "npm:inherits@2.0.1": {},
- "github:jspm/nodelibs@master": {
- "Base64": "npm:Base64@0.2",
- "base64-js": "npm:base64-js@^0.0.4",
- "ieee754": "npm:ieee754@^1.1.1",
- "inherits": "npm:inherits@^2.0.1",
- "json": "github:systemjs/plugin-json@master"
- }
- }
-});
-
-System.config({
- "versions": {
- "npm:humanize": "0.0.9",
- "npm:event-stream": "3.1.5",
- "npm:from": "0.1.3",
- "npm:map-stream": "0.1.0",
- "npm:pause-stream": "0.0.11",
- "npm:duplexer": "0.1.1",
- "npm:through": "2.3.4",
- "npm:split": "0.2.10",
- "npm:stream-combiner": "0.0.4",
- "github:jspm/nodelibs": [
- "master",
- "0.0.2"
- ],
- "npm:ieee754": "1.1.3",
- "npm:base64-js": "0.0.4",
- "npm:Base64": "0.2.1",
- "npm:inherits": "2.0.1",
- "github:systemjs/plugin-json": "master"
- }
-});
-
diff --git a/examples/pipetobrowser/browser/config/config.js b/examples/pipetobrowser/browser/config/config.js
deleted file mode 100644
index ce740a4..0000000
--- a/examples/pipetobrowser/browser/config/config.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * App configuration
- * @fileoverview
- */
-var veyronLogLevels = Veyron.logLevels;
-
-export var config = {
- veyron: {
- proxy: 'http://localhost:7776',
- logLevel: veyronLogLevels.INFO
- },
- namespaceRoot: '/proxy.envyor.com:8101',
- publishNamePrefix: 'google/p2b'
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/css/common-style.css b/examples/pipetobrowser/browser/libs/css/common-style.css
deleted file mode 100644
index cc263ea..0000000
--- a/examples/pipetobrowser/browser/libs/css/common-style.css
+++ /dev/null
@@ -1,32 +0,0 @@
-.hidden {
- display: none !important;
-}
-
-.invisible {
- visibility: hidden;
-}
-
-.secondary-text {
- color: rgba(0,0,0,.54);
-}
-
-.no-wrap {
- white-space: nowrap;
-}
-
-.screen-reader {
- position: absolute;
- top: -1000px;
- left: -1000px;
- width: 0px !important;
- height: 0px !important;
-}
-
-@-webkit-keyframes blink {
- 0% {
- opacity: 1;
- }
- 100% {
- opacity: 0.05;
- }
-}
diff --git a/examples/pipetobrowser/browser/libs/logs/logger.js b/examples/pipetobrowser/browser/libs/logs/logger.js
deleted file mode 100644
index 2e1b343..0000000
--- a/examples/pipetobrowser/browser/libs/logs/logger.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Logger represents a module that can write logging messages to the console.
- * @param {string} prefix A string that will be prefixed to every log message
- * @class
- */
-export class Logger {
- constructor(prefix) {
- prefix = prefix || 'Error';
- this.prefix_ = prefix;
- }
-
- debug(...args) {
- console.log('DEBUG: ' + this.prefix_ + ':', ...args);
- }
-};
diff --git a/examples/pipetobrowser/browser/libs/mvc/actions.js b/examples/pipetobrowser/browser/libs/mvc/actions.js
deleted file mode 100644
index ea667d2..0000000
--- a/examples/pipetobrowser/browser/libs/mvc/actions.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Actions are a similar concept to routes and simply provide an indirection
- * through string names to register and call functions.
- *
- * Using actions to group and call larger, self-contained functionality like
- * page transitions allows the framework to provide undo/back support by using
- * the history API or localStorage.
- *
- * Action handlers that are registered for an action, normally are controllers
- * that glue application services and state with views and handle events.
- * @overview
- */
-
-var registeredHandlers = {};
-
-/*
- * Registers an action and makes it available to be called using only a name.
- * @param {string} name Action's identifier
- * @param {function} handler Callback handler to register for the action.
- * handler will be called with the arguments pass from the caller when action
- * is triggered.
- */
-export function register(name, handler) {
- registeredHandlers[name] = handler;
-}
-
-/*
- * Calls an action's registered handler.
- * @param {string} name Action's identifier
- * @param {*} [...] args Arguments to be passed to the registered handler.
- * @return {*} Any result returned from the registered handler
- */
-export function trigger(name, ...args) {
- var handler = registeredHandlers[name];
- if(!handler) {
- throw new Error('No handler registered for action: ' + name);
- }
- return handler(...args);
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/mvc/view.js b/examples/pipetobrowser/browser/libs/mvc/view.js
deleted file mode 100644
index c4b8f50..0000000
--- a/examples/pipetobrowser/browser/libs/mvc/view.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Base class for all views.
- * View is a simple wrapper that represents a DOM element and exposes the public
- * API of that element. Web Components should be used to encapsulate View
- * functionality under a single DOM element and handle event binding/triggering,
- * templating, life-cycle management and attribute exposure and therefore those
- * features are not duplicated here.
- * @param {DOMelement} el DOM element this view wraps.
- * @class
- */
-export class View {
- constructor(el) {
- this._el = el;
- }
-
- get element() {
- return this._el;
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/blackhole/blackhole.jpg b/examples/pipetobrowser/browser/libs/ui-components/blackhole/blackhole.jpg
deleted file mode 100644
index eda4e30..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/blackhole/blackhole.jpg
+++ /dev/null
Binary files differ
diff --git a/examples/pipetobrowser/browser/libs/ui-components/blackhole/component.css b/examples/pipetobrowser/browser/libs/ui-components/blackhole/component.css
deleted file mode 100644
index b7c7a91..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/blackhole/component.css
+++ /dev/null
@@ -1,38 +0,0 @@
-:host {
- display: block;
- position: relative;
- margin: 0;
- padding: 0;
- background-image: url('blackhole.jpg');
- background-size: cover;
- background-repeat: no-repeat;
- background-position: 50% 50%;
- height: 100%;
- width: 100%;
-}
-
-.spinner {
- position: absolute;
- top: 50%;
- left: 50%;
- margin-left: -14px;
- margin-top: -14px;
-}
-
-.attribution {
- position: absolute;
- top: 0;
- right: 0;
- background-color: rgb(0, 0, 0);
- padding: 0.75em;
- font-size: 0.7em;
- text-decoration: none;
- font-style: normal;
- opacity: 0.3;
- color: #fafafa;
-}
-
-.attribution a {
- color: #02a8f3;
- text-decoration: none;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/blackhole/component.html b/examples/pipetobrowser/browser/libs/ui-components/blackhole/component.html
deleted file mode 100644
index f3c26d5..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/blackhole/component.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<link rel="import" href="../../../third-party/polymer/polymer.html">
-<!--
-p2b-ui-components-blackhole is a simple image of a blackhole in the middle of a galaxy
-when blackhole is running, a spinner gif is displayed in the middle of the blackhole.
--->
-<polymer-element name="p2b-blackhole">
- <template>
- <link rel="stylesheet" href="../../css/common-style.css">
- <link rel="stylesheet" href="component.css">
- <img class="spinner {{ !running ? 'hidden' : '' }}" src="{{ running ? 'libs/ui-components/common/spinner.gif' : '' }}" alt="Represents a blackhole destroying objects falling into it."/>
- <cite class="attribution">Photo from Wikipedia <a target="_blank" href="http://en.wikipedia.org/wiki/Black_hole#mediaviewer/File:BH_LMC.png">by Alan R</a> (CC BY-SA 2.5)</cite>
- </template>
- <script>
- Polymer('p2b-blackhole', {
- /*
- * Sets the blackhole in motion.
- */
- start: function() {
- this.running = true;
- },
- /*
- * Brings the blackhole to a halt!
- */
- stop: function() {
- this.running = false;
- }
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/common/spinner.gif b/examples/pipetobrowser/browser/libs/ui-components/common/spinner.gif
deleted file mode 100644
index ebb7cad..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/common/spinner.gif
+++ /dev/null
Binary files differ
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/common.css b/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/common.css
deleted file mode 100644
index bacc586..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/common.css
+++ /dev/null
@@ -1,14 +0,0 @@
-.filter-container {
- margin-bottom: 1.5em;
-}
-
-.filter-container h3 {
- margin: 0;
- margin-bottom: -10px;
-}
-
-.filter-container h3 {
- font-size: 1em;
- color: #9e9e9e;
- font-weight: normal;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/component.css b/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/component.css
deleted file mode 100644
index a01a3bc..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/component.css
+++ /dev/null
@@ -1,19 +0,0 @@
-paper-checkbox, paper-radio-button {
- padding: 16px 16px 0px 12px !important;
-}
-
-paper-checkbox::shadow #ink[checked] {
- color: #4285f4;
-}
-
-paper-checkbox::shadow #checkbox.checked {
- border-color: #4285f4;
-}
-
-paper-radio-button::shadow #ink[checked] {
- color: #e91e63;
-}
-
-paper-radio-button::shadow #onRadio {
- background-color: #e91e63;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/component.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/component.html
deleted file mode 100644
index e7c3b41..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/component.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<link rel="import" href="../../../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../../../third-party/paper-checkbox/paper-checkbox.html">
-<link rel="import" href="../../../../../third-party/paper-radio-button/paper-radio-button.html">
-<link rel="import" href="../../../../../third-party/paper-radio-group/paper-radio-group.html">
-<polymer-element name="p2b-grid-filter-select" attributes="multiple key label" grid-filter expects-grid-state>
- <template>
- <link rel="stylesheet" href="component.css">
- <link rel="stylesheet" href="../common.css">
- <content id="content" select="*"></content>
- <div class="filter-container">
- <h3>{{label}}</h3>
- <template if="{{ multiple }}" bind>
- <core-selector id="multiSelector" multi selectedAttribute="checked" valueattr="value" core-select="{{updateGridState}}" selected="{{ selected }}">
- <template repeat="{{ item in items }}">
- <paper-checkbox value="{{ item.value }}" on-change="{{ updateGridState }}" label="{{ item.label }}"></paper-checkbox>
- </template>
- </core-selector>
- </template>
-
- <template if="{{ !multiple }}" bind>
- <paper-radio-group id="singleSelector" valueattr="value" selected="{{ selected }}">
- <template repeat="{{ item in items }}">
- <paper-radio-button value="{{ item.value }}" on-change="{{ updateGridState }}" label="{{ item.label }}"></paper-radio-button>
- </template>
- </paper-radio-group>
- </template>
- </div>
- </template>
- <script>
- Polymer('p2b-grid-filter-select', {
- /*
- * Whether multiple items can be selected
- * @type {boolean}
- */
- multiple: false,
-
- /*
- * Key that will be added to filters map passed to the fetch() function of your data source.
- * @type {string}
- */
- key: '',
-
- ready: function() {
- // find the selected items from the child nodes
- this.items = Array.prototype.slice.call(this.$.content.getDistributedNodes());
- for(var i=0; i < this.items.length; i++){
- if(this.items[i].checked) {
- if(this.multiple) {
- this.selected = this.selected || [];
- this.selected.push(this.items[i].value);
- } else {
- this.selected = this.items[i].value;
- }
- }
- }
- },
-
- updateGridState: function() {
- if( this.multiple ) {
- // quirk: we need to copy the array so change is observed. .slice() does that
- this.gridState.filters[this.key] = this.$.multiSelector.selected.slice();
- } else {
- this.gridState.filters[this.key] = this.$.singleSelector.selected.slice();
- }
- }
-
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/item/component.css b/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/item/component.css
deleted file mode 100644
index e69de29..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/item/component.css
+++ /dev/null
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/item/component.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/item/component.html
deleted file mode 100644
index 7d46b8f..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/select/item/component.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<link rel="import" href="../../../../../../third-party/polymer/polymer.html">
-<polymer-element name="p2b-grid-filter-select-item" attributes="label checked value">
- <script>
- Polymer('p2b-grid-filter-select-item', {
- /*
- * Label text for the item
- * @type {string}
- */
- label: '',
-
- /*
- * Whether toggle is checked or not
- * @type {boolean}
- */
- checked: false,
-
- /*
- * Value that will available as filters[key] in the fetch() function of your data source.
- * Where key is the key of the select filter that contains this item
- * @type {string}
- */
- value: ''
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/toggle/component.css b/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/toggle/component.css
deleted file mode 100644
index eb2aa4b..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/toggle/component.css
+++ /dev/null
@@ -1,3 +0,0 @@
-paper-toggle-button {
- padding: 16px 16px 0px 12px !important;
-}
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/toggle/component.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/toggle/component.html
deleted file mode 100644
index a7c9414..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/filter/toggle/component.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<link rel="import" href="../../../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../../../third-party/paper-toggle-button/paper-toggle-button.html">
-<polymer-element name="p2b-grid-filter-toggle" attributes="key checked label" grid-filter expects-grid-state>
- <template>
- <link rel="stylesheet" href="component.css">
- <link rel="stylesheet" href="../common.css">
- <div class="filter-container">
- <h3>{{label}}</h3>
- <paper-toggle-button id="toggle" on-change="{{ updateGridState }}" checked?="{{ checked }}"></paper-toggle-button>
- </div>
- </template>
- <script>
- Polymer('p2b-grid-filter-toggle', {
- /*
- * Label text for the toggle filter
- * @type {string}
- */
- label: '',
-
- /*
- * Whether toggle is checked or not
- * @type {boolean}
- */
- checked: false,
-
- /*
- * Key that will be added to filters map passed to the fetch() function of your data source.
- * @type {string}
- */
- key: '',
- updateGridState: function() {
- this.gridState.filters[this.key] = this.$.toggle.checked;
- }
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/cell/renderer.css b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/cell/renderer.css
deleted file mode 100644
index 4ee59db..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/cell/renderer.css
+++ /dev/null
@@ -1,9 +0,0 @@
-.cell {
- overflow: hidden;
- text-overflow: ellipsis;
- padding: 0.75em 0.5em;
-}
-
-:host {
- overflow: hidden;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/cell/renderer.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/cell/renderer.html
deleted file mode 100644
index 514bebe..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/cell/renderer.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<link rel="import" href="../../../../../third-party/polymer/polymer.html">
-<polymer-element name="p2b-grid-cell-renderer" extends="td" attributes="data">
- <template>
- <link rel="stylesheet" href="renderer.css">
- <link rel="stylesheet" href="../../../../css/common-style.css">
- <div class="cell {{ {'secondary-text': !data.primary, 'no-wrap': !data.wrap} | tokenList }}">
- <content></content>
- </div>
- </template>
- <script>
- /*
- * @private
- */
- Polymer('p2b-grid-cell-renderer', {
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/component.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/component.html
deleted file mode 100644
index cbb8052..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/component.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<link rel="import" href="../../../../../third-party/polymer/polymer.html">
-<polymer-element name="p2b-grid-column" grid-column attributes="label sortable key primary wrap flex minFlex priority">
- <script>
- Polymer('p2b-grid-column', {
- /*
- * Label text for the column
- * @type {string}
- */
- label: '',
-
- /*
- * number specifying how flexible the width of the column is
- * compared to other columns. For instance for a grid with three columns
- * flex values of 1, 3, 1. means the middle column needs to be three times
- * as wide as the other two.
- * Flex value of 0 means the column should not be displayed.
- * Flex values for all the columns can add up to any value.
- * @type {integer}
- */
- flex: 1,
-
- /*
- * minimum Flex value that this column can be reduced to by the responsive data grid
- * Defaults to 1 meaning column can be reduced to 1 flex as available space shrinks.
- * @type {integer}
- */
- minFlex: 1,
-
- /*
- * specifies the importance of this column. Responsive grid uses this number
- * to decide which columns to reduce/hide when available space shrinks.
- * Lower number means more important.
- * @type {integer}
- */
- priority: 1,
-
- /*
- * whether this column is sortable
- * @type {boolean}
- */
- sortable: false,
-
- /*
- * whether this the primary column of the grid.
- * Normally there is a single column that other columns are dependents on
- * @type {boolean}
- */
- primary: false,
-
-
- /*
- * whether text inside the cells of this columns are allowed to wrap.
- * @type {boolean}
- */
- wrap: false,
-
- /*
- * Key that will be pass as sort.key to fetch() function of your data source.
- * @type {string}
- */
- key: ''
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/renderer.css b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/renderer.css
deleted file mode 100644
index b87be43..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/renderer.css
+++ /dev/null
@@ -1,26 +0,0 @@
-:host {
- color: rgba(0,0,0, 0.26);
- font-weight: normal;
- text-align: left;
- white-space: nowrap;
-}
-
-paper-button {
- text-align: left;
- width: 100%;
- text-transform: none;
-}
-
-paper-button[disabled] {
- background: inherit !important;
- color: inherit !important;
-}
-
-paper-button[disabled] {
- background: inherit !important;
- color: inherit !important;
-}
-
-paper-button::shadow #ripple {
- color: #0f9d58;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/renderer.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/renderer.html
deleted file mode 100644
index 208ff49..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/column/renderer.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<link rel="import" href="../../../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../../../third-party/paper-button/paper-button.html">
-<polymer-element name="p2b-grid-column-renderer" extends="th" attributes="data gridState" expects-grid-state>
- <template>
- <link rel="stylesheet" href="renderer.css">
- <paper-button label="{{ formattedLabel }}" disabled?="{{!data.sortable}}" on-tap="{{ updateGridState }}"></paper-button>
- </template>
- <script>
- /*
- * @private
- */
- Polymer('p2b-grid-column-renderer', {
- 'observe': {
- 'data.flex' : 'updateWidth',
- 'data.totalFlex' : 'updateWidth'
- },
-
- domReady: function() {
- this.updateWidth();
- },
-
- updateWidth: function() {
- // calculate the width value based on flex and total flex of the whole grid.
- this.style.width = (this.data.flex / this.data.totalFlex) * 100 + '%';
- },
-
- updateGridState:function() {
- if( !this.data.sortable ) {
- return;
- }
- this.gridState.sort.ascending = !this.gridState.sort.ascending;
- this.gridState.sort.key = this.data.key;
- },
-
- get formattedLabel() {
- if (!this.data.sortable || this.gridState.sort.key != this.data.key) {
- return this.data.label;
- }
-
- if (this.gridState.sort.ascending) {
- return this.data.label + ' \u21A5'; // up wedge unicode character
- } else {
- return this.data.label + ' \u21A7'; // down wedge unicode character
- }
- }
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.css b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.css
deleted file mode 100644
index b309a31..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.css
+++ /dev/null
@@ -1,100 +0,0 @@
-table {
- border-collapse: collapse;
- table-layout: fixed;
- width: 100%;
- border-spacing: 0;
- margin-top: 15px;
-}
-
-thead tr {
- border-bottom: solid 1px rgba(0,0,0, .12);
- padding-bottom: 0.75em;
-}
-
-thead tr th {
- position: relative;
-}
-
-td {
- overflow: hidden;
- vertical-align: top;
-}
-
-table tbody tr:nth-child(2) td {
- padding-top: 15px;
-}
-
-.more-icon {
- fill: #0a7e07;
- color: #0a7e07;
-}
-
-paper-dialog {
- max-width: 80em;
- width: 80vw;
-}
-
-.more-dialog-content .heading {
- font-size: 1.0em;
- padding-top: 0.2em;
- padding-bottom: 0.2em;
- color: #4285f4;
- border-bottom: 1px solid rgba(0,0,0,0.05);
- font-weight: normal;
- text-transform: uppercase;
- margin: 0;
-}
-
-.more-dialog-content .details {
- margin-bottom: 1em;
-}
-
-.search-fab {
- position: absolute;
- right: 20px;
- top: 10px;
- background-color: #03a9f4;
-}
-
-#searchTools {
- box-shadow: rgba(0, 0, 0, 0.14902) 2px 2px 4px;
- background-color: #f5f5f5;
- padding: 1em;
- padding-bottom: 0;
-}
-
-.result-count {
- font-size: 0.8em;
- color: #616161;
- float: right;
-}
-
-.info-column {
- text-align: center;
-}
-
-[moreInfoOnly] {
- display: none;
-}
-
-.more-dialog-content [moreInfoOnly] {
- display: initial;
-}
-
-.more-dialog-content [gridOnly] {
- display:none;
-}
-
-.paginator {
- display: inline-block;
- border: solid 1px rgba(0, 0, 0, 0.05);
- box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
- color: rgba(0, 0, 0, 0.54);
- fill: rgba(0, 0, 0, 0.54);
- margin: 1em;
- font-size: 0.9em;
-}
-
-.paginator paper-icon-button {
- vertical-align: middle;
-}
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.html
deleted file mode 100644
index 4f555ab..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/component.html
+++ /dev/null
@@ -1,446 +0,0 @@
-<link rel="import" href="../../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../../third-party/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="../../../../third-party/paper-dialog/paper-dialog.html">
-<link rel="import" href="../../../../third-party/paper-dialog/paper-dialog-transition.html">
-<link rel="import" href="../../../../third-party/paper-fab/paper-fab.html">
-<link rel="import" href="../../../../third-party/core-collapse/core-collapse.html">
-<link rel="import" href="row/renderer.html">
-<link rel="import" href="cell/renderer.html">
-<link rel="import" href="column/renderer.html">
-
-<polymer-element name="p2b-grid" attributes="summary dataSource defaultSortKey defaultSortAscending pageSize">
- <template>
- <link rel="stylesheet" href="../../../css/common-style.css">
- <link rel="stylesheet" href="component.css">
- <div id="templates"></div>
- <core-collapse id="searchTools">
- <div class="result-count">Showing {{ dataSourceResult.length }} items of {{totalNumItems}}</div>
- <div>
- <content select="[grid-search]"></content>
- </div>
- <div>
- <content select="[grid-filter]"></content>
- </div>
- </core-collapse>
- <table id="table" summary="{{ summary }}" cellpadding="0" cellpadding="0" border="0" style="visibility:hidden" >
- <thead>
- <tr>
- <th is="p2b-grid-column-renderer" gridState="{{ gridState }}" data="{{ col.columnData }}" repeat="{{ col in columns }}" template></th>
- <th style="width:40px"> <span class="screen-reader">More info</span>
- <paper-fab class="search-fab" focused icon="search" on-tap="{{ toggleSearchTools }}"></paper-fab>
- </th>
- </tr>
- </thead>
- <tbody>
- <!-- quirk: Shadow Dom breaks parent-child relationships in HTML, this causes issues with
- elements like table. Ideally we could have had <grid><grid-row><grid-cell> but we can't do
- that yet since the tr and td rendered by <grid-row> <grid-cell> will be in shadow Dom and isolated.
- Chromium bug: https://code.google.com/p/chromium/issues/detail?id=374315
- W3C Spec bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=15616
- -->
- <tr is="p2b-grid-row-renderer" repeat="{{ item in dataSourceResult }}" template>
- <td is="p2b-grid-cell-renderer" data="{{ col.columnData }}" repeat="{{ col in columns }}" template>
- <template ref="{{ col.cellTemplateId }}" bind></template>
- </td>
- <td class="info-column">
- <paper-icon-button on-click="{{ showMoreInfo }}" class="more-icon" icon="more-vert" title="more info"></paper-icon-button
- >
- </td>
- </tr>
- </tbody>
- </table>
-
- <!-- Pagination -->
- <template if="{{totalNumPages > 1}}">
- <div class="paginator">
- <paper-icon-button title="Previous page" icon="hardware:keyboard-arrow-left"
- class="{{ {invisible : pageNumber == 1} | tokenList }}" on-click="{{ previousPage }}"></paper-icon-button>
- <span>Page {{ pageNumber }} of {{ totalNumPages }}</span>
- <paper-icon-button title="Next page" icon="hardware:keyboard-arrow-right"
- class="{{ {invisible : onLastPage } | tokenList }}" on-click="{{ nextPage }}"></paper-icon-button>
- </div>
- </template>
-
- <!-- Dialog that displays all columns and their values when more info icon activated -->
- <paper-dialog id="dialog" heading="Details" transition="paper-dialog-transition-bottom">
- <template id="moreInfoTemplate" bind>
- <div class="more-dialog-content">
- <template repeat="{{ item in selectedItems }}">
- <template repeat="{{ col in columns }}">
- <h3 class="heading">{{ col.columnData.label }}</h3>
- <div class="details"><template ref="{{ col.cellTemplateId }}" bind></template></div>
- </template>
- </template>
- </div>
- </template>
- <paper-button label="Close" dismissive></paper-button>
- </paper-dialog>
-
- </template>
- <script>
- /*
- * Reusable grid that can host search, filters and supports sortable columns and custom cell renderer
- * @example usage:
-
- <p2b-grid defaultSortKey="firstName"
- defaultSortAscending
- dataSource="{{ myContactsDataSource }}"
- summary="Displays your contacts in a tabular format">
-
- <!-- Search contacts-->
- <p2b-grid-search label="Search Contacts"></p2b-grid-search>
-
- <!-- Filter for circles -->
- <p2b-grid-filter-select multiple key="circle" label="Circles">
- <p2b-grid-filter-select-item checked label="Close Friends" value="close"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item label="Colleagues" value="far"></p2b-grid-filter-select-item>
- </p2b-grid-filter-select>
-
- <!-- Toggle to allow filtering by online mode-->
- <p2b-grid-filter-toggle key="online" label="Show online only" checked></p2b-grid-filter-toggle>
-
- <!-- Columns, sorting and cell templates -->
- <p2b-grid-column sortable label="First Name" key="firstName" />
- <template>{{ item.firstName }}</template>
- </p2b-grid-column>
-
- <p2b-grid-column sortable label="Last Name" key="lastName" />
- <template>
- <span style="text-transform:uppercase;">
- {{ item.lastName }}
- </span>
- </template>
- </p2b-grid-column>
-
- <p2b-grid-column label="Circle" key="circle"/>
- <template>
- <img src="images\circls\{{ item.circle }}.jpg" alt="in {{ item.circle }} circle"><img>
- </template>
- </p2b-grid-column>
-
- </p2b-grid>
-
- * DataSource attribute expects an object that has a fetch(search, sort, filters) method. Please see
- * documentation on DataSource property for details.
- */
- Polymer('p2b-grid', {
- /*
- * DataSource is an object that has a fetch(search, sort, filters) method where
- * search{key<string>} is current search keyword
- * sort{key<string>, ascending<bool>} current sort key and direction
- * filter{map{key<string>, values<Array>}} Map of filter keys to currently selected filter values
- * search, sort and filters are provided by the grid control whenever they are changed by the user.
- * DataSource is called automatically by the grid when user interacts with the component
- * Grid does some batching of user actions and only calls fetch when needed in a requestAnimationFrame
- * Keys provided for sort and filters correspond to keys set in the markup when constructing the grid.
- * DataSource.fetch() is expected to return an array of filtered sorted results of the items.
- */
- dataSource: null,
-
- /*
- * Summary for the grid.
- * @type {string}
- */
- summary: '',
-
- /*
- * Initial sort key
- * @type {string}
- */
- defaultSortKey: '',
-
- /*
- * Initial sort direction
- * @type {string}
- */
- defaultSortAscending: false,
-
- /*
- * Number if items displayed in each page.
- * Defaults to 20
- * @type {integer}
- */
- pageSize: 20,
-
- showMoreInfo: function(e) {
- var item = e.target.templateInstance.model.item;
- this.selectedItems = [item];
- this.$.dialog.toggle();
- },
-
- ready: function() {
-
- // private property fields
- this.columns = [];
- this.pageNumber = 1;
- this.dataSource = null;
- this.cachedDataSourceResult = [];
- this.dataSourceResult = [];
- this.gridState = {
- sort: {
- key: '',
- ascending: false
- },
- search: {
- keyword: ''
- },
- filters: {}
- },
-
- // set the default sort and direction on the state object
- this.gridState.sort.key = this.defaultSortKey;
- this.gridState.sort.ascending = this.defaultSortAscending;
-
- this.initTemplates(); // loads cell templates
- this.initGridStateDependents(); // initialize filters and search
- this.initGridStateObserver(); // observe changes to grid state by filters
-
- },
-
- /*
- * Called by Polymer when DOM is read.
- * @private
- */
- domReady: function() {
- this.adjustFlexWidths();
- this.$.table.style.visibility = 'visible';
- },
-
- /*
- * Called by Polymer when dataSource attribute changes.
- * @private
- */
- dataSourceChanged: function() {
- this.refresh(true);
- },
-
- /*
- * Sets up an object observer to get any mutations on the grid state object.
- * Filters or sortable columns can change the state and we like to refresh
- * when changes happens.
- * @private
- */
- initGridStateObserver: function() {
- var self = this;
- for (key in this.gridState) {
- var observer = new ObjectObserver(this.gridState[key])
- observer.open(function() {
- // refresh the grid on any mutations and go back to page one
- self.refresh(true);
- });
- }
- },
-
- /*
- * Copies the cell templates as defined by the user for each column into
- * the grid so that we can reference them in a loop.
- * quirk: Need to reference them by Id so a new Id is generated for each one
- * Ids are scoped in the shadow DOM so no collisions.
- * @private
- */
- initTemplates: function() {
- var self = this;
- var columnNodes = this.querySelectorAll('[grid-column]');
- var totalFlex = 0;
- for (var i = 0; i < columnNodes.length; i++) {
- var col = columnNodes[i];
- var cellTemplate = col.querySelector('template');
- this.originalContext = cellTemplate.model;
- var cellTemplateId = "userProvidedCellTemplate" + i;
- cellTemplate.id = cellTemplateId;
- this.$.templates.appendChild(cellTemplate);
- totalFlex += col.flex;
- col.origFlex = col.flex;
- this.columns.push({
- cellTemplateId: cellTemplateId,
- columnData: col
- });
- }
-
- // add up the total value of flex attribute on each column and add it to data
- this.columns.forEach(function(c) {
- c.columnData.totalFlex = totalFlex;
- });
-
- // readjust the widths on resize
- var previousTableWidth = self.$.table.offsetWidth;
- onResizeHandler = function() {
- var newWidth = self.$.table.offsetWidth;
- if (newWidth != previousTableWidth && newWidth > 0) {
- self.adjustFlexWidths();
- }
- previousTableWidth = newWidth;
- };
-
- // quirks: since there is no good way to know if width changes, we pull.
- // window.resize does not cover all resize cases
- this.resizeInterval = setInterval(onResizeHandler, 50);
- },
-
- /*
- * Called by Polymer when DOM is gone. We need to unbind custom event listeners here.
- * @private
- */
- detached: function() {
- clearInterval(this.resizeInterval);
- },
-
- /*
- * Provide the grid state to any component that expects it so they can mutate
- * without the grid needing to know about them at all.
- * @private
- */
- initGridStateDependents: function() {
- var gridStateDependents = this.querySelectorAll('[expects-grid-state]');
- for (var i = 0; i < gridStateDependents.length; i++) {
- gridStateDependents[i].gridState = this.gridState;
- }
- },
-
- /*
- * Refreshed the grid by fetching the data again and updating the UI in the next render tick
- * @param {bool} goBackToPageOne Optional parameter indicating that grid should go back
- * to page 1 after refresh. false by default
- */
- refresh: function(goBackToPageOne) {
- var self = this;
- requestAnimationFrame(function() {
- if (goBackToPageOne) {
- self.pageNumber = 1;
- }
- self.updateDataSource();
- });
- },
-
- /*
- * Performs responsive changes for the grid.
- * Values of flex, minFlex and priority attributes on the grid column decides
- * the responsive behavior.
- * Grid assumes the original total number of columns can fit on a 768px width,
- * if width of the grid container is less than that, then it starts to reduce
- * flex values for each columns in reverse priority one by one until it reaches
- * the minFlex value for all columns.
- * If it still needs to reduce the width of the table at this point, it starts hiding
- * columns in reverse priority order.
- */
- adjustFlexWidths: function() {
- var minWidth = 768;
- var tableWidth = this.$.table.offsetWidth;
-
- // reset to original flex values
- for (var i = 0; i < this.columns.length; i++) {
- var col = this.columns[i];
- col.columnData.flex = col.columnData.origFlex;
- }
-
- if (tableWidth === 0 || tableWidth >= minWidth) {
- return;
- }
-
- // total of all flex values from all columns
- var totalFlex = this.columns.reduce( function(prev, col) {
- return prev + col.columnData.flex;
- }, 0);
-
- // number of pixels per flex point
- var pixelPerFlex = Math.floor(tableWidth / totalFlex);
- // number of flex points we need to eliminate to same pixelPerFlex as the minWidth case
- var numFlexToEliminate = Math.ceil((minWidth - tableWidth) / pixelPerFlex);
-
- // sort from least important to most important
- var sortedColumnsData = this.columns.map(function(col) {
- return col.columnData
- }).sort(function(a, b) {
- return b.priority - a.priority;
- });
-
- // first try to reduce each flex value until we hit min-flex for each column
- var numElimintedFlex = 0
- var numIrreducableColumns = 0;
- var numColumns = sortedColumnsData.length;
- while (numElimintedFlex < numFlexToEliminate && numIrreducableColumns < numColumns) {
- for (var i = 0; i < numColumns; i++) {
- var col = sortedColumnsData[i];
- if (col.flex > col.minFlex) {
- col.flex--;
- numElimintedFlex++;
- } else {
- numIrreducableColumns++;
- }
- }
- }
-
- // if still need to reduce, start eliminating whole columns based on priority
- // never eliminate the top priority column, hence only iterate to numColumns - 1
- if (numElimintedFlex < numFlexToEliminate) {
- for (var i = 0; i < numColumns - 1 && numElimintedFlex < numFlexToEliminate; i++) {
- var col = sortedColumnsData[i];
- numElimintedFlex += col.flex;
- col.flex = 0;
- }
- }
-
- // update the new totalFlex for each column
- this.columns.forEach(function(c) {
- c.columnData.totalFlex = totalFlex - numFlexToEliminate;
- });
- },
-
- /*
- * dataSourceResult is what the UI binds to and integrate over.
- * Only fetches data if scheduled to do so
- * @private
- */
- updateDataSource: function() {
- if (!this.dataSource) {
- return;
- }
-
- // fetch the data
- this.cachedDataSourceResult = this.dataSource.fetch(
- this.gridState.search,
- this.gridState.sort,
- this.gridState.filters
- );
-
- // page the data
- this.totalNumItems = this.cachedDataSourceResult.length;
- // if there less data than current page number, go back to page 1
- if (this.totalNumItems < (this.pageNumber - 1) * this.pageSize) {
- this.pageNumber = 1;
- }
- this.totalNumPages = Math.ceil(this.totalNumItems / this.pageSize);
- this.onLastPage = this.totalNumPages == this.pageNumber;
-
- // skip and take
- var startIndex = (this.pageNumber - 1) * this.pageSize;
- var endIndex = startIndex + this.pageSize;
- this.cachedDataSourceResult = this.cachedDataSourceResult.slice(startIndex, endIndex);
-
- this.dataSourceResult = this.cachedDataSourceResult;
- },
-
- /*
- * collapse/show search and filter container.
- * @private
- */
- toggleSearchTools: function() {
- this.$.searchTools.toggle();
- },
-
- nextPage: function() {
- if (!this.onLastPage) {
- this.pageNumber++;
- this.refresh();
- }
- },
-
- previousPage: function() {
- if (this.pageNumber > 1) {
- this.pageNumber--;
- this.refresh();
- }
- }
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/row/renderer.css b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/row/renderer.css
deleted file mode 100644
index e69de29..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/row/renderer.css
+++ /dev/null
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/row/renderer.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/row/renderer.html
deleted file mode 100644
index 02c8c02..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/grid/row/renderer.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<link rel="import" href="../../../../../third-party/polymer/polymer.html">
-<polymer-element name="p2b-grid-row-renderer" extends="tr">
- <template>
- <link rel="stylesheet" href="renderer.css">
- <content></content>
- </template>
- <script>
- /*
- * @private
- */
- Polymer('p2b-grid-row-renderer', {
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/search/component.css b/examples/pipetobrowser/browser/libs/ui-components/data-grid/search/component.css
deleted file mode 100644
index ba87339..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/search/component.css
+++ /dev/null
@@ -1,4 +0,0 @@
-paper-input {
- width: 50%;
- color: #9e9e9e;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/ui-components/data-grid/search/component.html b/examples/pipetobrowser/browser/libs/ui-components/data-grid/search/component.html
deleted file mode 100644
index 93b51db..0000000
--- a/examples/pipetobrowser/browser/libs/ui-components/data-grid/search/component.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<link rel="import" href="../../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../../third-party/paper-input/paper-input.html">
-<polymer-element name="p2b-grid-search" grid-search expects-grid-state attributes="label">
- <template>
- <link rel="stylesheet" href="component.css">
- <paper-input inputValue="{{ value }}" id="search" label="{{ label }}"></paper-input>
- </template>
- <script>
- /*
- * Renders a search box inside the grid components
- */
- Polymer('p2b-grid-search', {
- /*
- * Label text for the search
- * @type {string}
- */
- label: '',
- valueChanged: function() {
- this.gridState.search.keyword = this.value;
- }
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/libs/utils/byte-object-stream-adapter.js b/examples/pipetobrowser/browser/libs/utils/byte-object-stream-adapter.js
deleted file mode 100644
index 90593e1..0000000
--- a/examples/pipetobrowser/browser/libs/utils/byte-object-stream-adapter.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import { default as Stream } from "nodelibs/stream"
-import { default as buffer } from "nodelibs/buffer"
-
-var Transform = Stream.Transform;
-var Buffer = buffer.Buffer;
-
-/*
- * Adapts a stream of byte arrays in object mode to a regular stream of Buffer
- * @class
- */
-export class ByteObjectStreamAdapter extends Transform {
- constructor() {
- super();
- this._writableState.objectMode = true;
- this._readableState.objectMode = false;
- }
-
- _transform(bytesArr, encoding, cb) {
- var buf = new Buffer(new Uint8Array(bytesArr));
- this.push(buf);
-
- cb();
- }
-}
diff --git a/examples/pipetobrowser/browser/libs/utils/exists.js b/examples/pipetobrowser/browser/libs/utils/exists.js
deleted file mode 100644
index 9ea45b3..0000000
--- a/examples/pipetobrowser/browser/libs/utils/exists.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Given a collection of objects, returns true if all of them exist
- * Returns false as soon as one does not exist.
- * @param {*} [...] objects Objects to check existence of
- * @return {bool} Whether all of the given objects exist or not
- */
-export function exists(...objects) {
- for (var obj of objects) {
- if (typeof obj === 'undefined' || obj === null) {
- return false;
- }
- }
-
- return true;
-}
diff --git a/examples/pipetobrowser/browser/libs/utils/formatting.js b/examples/pipetobrowser/browser/libs/utils/formatting.js
deleted file mode 100644
index 26f90e6..0000000
--- a/examples/pipetobrowser/browser/libs/utils/formatting.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import { default as humanize } from 'npm:humanize'
-
-export function formatDate(d) {
- if(d === undefined || d == null) { return; }
- var naturalDay = humanize.naturalDay(d.getTime() / 1000);
- var naturalTime = humanize.date('g:i a', d);
- return naturalDay + ' at ' + naturalTime;
-}
-
-export function formatRelativeTime(d) {
- if(d === undefined || d == null) { return; }
- return humanize.relativeTime(d.getTime() / 1000);
-}
-
-export function formatInteger(n) {
- if(n === undefined || n == null) { return; }
- return humanize.numberFormat(n, 0);
-}
-
-export function formatBytes(b) {
- if(b === undefined || b == null) { return; }
- return humanize.filesize(b);
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/utils/stream-byte-counter.js b/examples/pipetobrowser/browser/libs/utils/stream-byte-counter.js
deleted file mode 100644
index eef02ee..0000000
--- a/examples/pipetobrowser/browser/libs/utils/stream-byte-counter.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { default as Stream } from "nodelibs/stream"
-
-var Transform = Stream.Transform;
-/*
- * A through transform stream that counts number of bytes being piped to it
- * @param {function} onUpdate Callback function that gets called with number of
- * bytes read when a chunk is read
- * @class
- */
-export class StreamByteCounter extends Transform {
- constructor(onUpdate) {
- super();
- this._onUpdate = onUpdate;
- }
-
- _transform(chunk, encoding, cb) {
- this._onUpdate(chunk.length);
- this.push(chunk)
- cb();
- }
-}
diff --git a/examples/pipetobrowser/browser/libs/utils/stream-copy.js b/examples/pipetobrowser/browser/libs/utils/stream-copy.js
deleted file mode 100644
index c940213..0000000
--- a/examples/pipetobrowser/browser/libs/utils/stream-copy.js
+++ /dev/null
@@ -1,60 +0,0 @@
-import { default as Stream } from "nodelibs/stream"
-import { default as buffer } from "nodelibs/buffer"
-
-var Transform = Stream.Transform;
-var PassThrough = Stream.PassThrough;
-var Buffer = buffer.Buffer;
-/*
- * A through transform stream keep a copy of the data piped to it and provides
- * functions to create new copies of the stream on-demand
- * @class
- */
-export class StreamCopy extends Transform {
- constructor() {
- super();
- this._writableState.objectMode = true;
- this._readableState.objectMode = true;
- // TODO(aghassemi) make this a FIFO buffer with reasonable max-size
- this.buffer = [];
- this.copies = [];
- var self = this;
- this.on('end', () => {
- self.ended = true;
- for (var i=0; i < self.copies.length; i++) {
- self.copies[i].end();
- }
- });
- }
-
- _transform(chunk, encoding, cb) {
- this.buffer.push(chunk);
- this.push(chunk);
- for (var i=0; i < this.copies.length; i++) {
- this.copies[i].push(chunk);
- }
- cb();
- }
-
- /*
- * Create a new copy of the stream
- * @param {bool} onlyNewData Whether the copy should include
- * existing data from the stream or just new data.
- * @return {Stream} Copy of the stream
- */
- copy(onlyNewData) {
- var copy = new PassThrough( { objectMode: true });
- if (!onlyNewData) {
- // copy existing data first in the order received
- for (var i = 0; i < this.buffer.length; i++) {
- copy.push(this.buffer[i]);
- }
- }
- if (this.ended) {
- copy.push(null);
- } else {
- this.copies.push(copy);
- }
-
- return copy;
- }
-}
diff --git a/examples/pipetobrowser/browser/libs/utils/stream-helpers.js b/examples/pipetobrowser/browser/libs/utils/stream-helpers.js
deleted file mode 100644
index 5ce53a3..0000000
--- a/examples/pipetobrowser/browser/libs/utils/stream-helpers.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import { default as es } from "npm:event-stream"
-
-export var streamUtil = {
- split: es.split,
- map: es.map,
- writeArray: es.writeArray
-};
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/utils/url.js b/examples/pipetobrowser/browser/libs/utils/url.js
deleted file mode 100644
index 266c003..0000000
--- a/examples/pipetobrowser/browser/libs/utils/url.js
+++ /dev/null
@@ -1,10 +0,0 @@
-var hasProtocol = new RegExp('^(?:[a-z]+:)?//', 'i');
-
-/*
- * Decides whether a string is an absolute Url by seeing if it starts with a protocol.
- * @param {string} val string value to check.
- * @return {bool} whether or not the string value is a Url
- */
-export function isAbsoulteUrl(val) {
- return hasProtocol.test(val);
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/libs/utils/web-component-loader.js b/examples/pipetobrowser/browser/libs/utils/web-component-loader.js
deleted file mode 100644
index bb37e0c..0000000
--- a/examples/pipetobrowser/browser/libs/utils/web-component-loader.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export function importComponent(path) {
- return new Promise((resolve, reject) => {
- var link = document.createElement('link');
- link.setAttribute('rel', 'import');
- link.setAttribute('href', path);
- link.onload = function() {
- resolve();
- };
- document.body.appendChild(link);
- });
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/package.json b/examples/pipetobrowser/browser/package.json
deleted file mode 100644
index 93fe433..0000000
--- a/examples/pipetobrowser/browser/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "registry": "jspm",
- "main": "app",
- "directories": {
- "jspmPackages": "third-party"
- },
- "dependencies": {
- "npm:event-stream": "^3.1.5",
- "npm:humanize": "^0.0.9",
- "nodelibs": "master"
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/common/common.css b/examples/pipetobrowser/browser/pipe-viewers/builtin/common/common.css
deleted file mode 100644
index e69de29..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/common/common.css
+++ /dev/null
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.css b/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.css
deleted file mode 100644
index d1ef530..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.css
+++ /dev/null
@@ -1,26 +0,0 @@
-:host {
- background-color: #000000;
- height: 100%;
- display: block;
- overflow: auto;
-}
-
-pre {
- margin: 0;
- padding: 0.5em;
-
- font-family: Fixed, monospace;
- line-height: 1.2em;
- word-break: break-word;
-
- color: #ffffff;
-}
-
-.auto-scroll {
- position: fixed;
- right: 40px;
- bottom: 0;
- opacity: 0.8;
- padding: 0.8em;
- background-color: #ffeb3b;
-}
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.html b/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.html
deleted file mode 100644
index 5505f9b..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/component.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<link rel="import" href="../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../third-party/paper-checkbox/paper-checkbox.html">
-
-<polymer-element name="p2b-plugin-console">
- <template>
- <link rel="stylesheet" href="component.css">
- <link rel="stylesheet" href="../../../libs/css/common-style.css">
- <div title="Auto Scroll" class="auto-scroll {{ {hidden : !scrolling} | tokenList}}">
- <paper-checkbox checked="{{autoScroll}}" label="Auto Scroll" id="autoscroll"></paper-checkbox>
- </div>
- <pre id="console"></pre>
- </template>
- <script>
- Polymer('p2b-plugin-console', {
- ready: function() {
- this.textBuffer = [];
- this.autoScroll = true;
- },
-
- attached: function() {
- this.renderLoop();
- },
- detached: function() {
- this.isDetached = true;
- },
- renderLoop: function() {
- var self = this;
- if (!this.isDetached) {
- requestAnimationFrame(function() {
- self.render();
- self.renderLoop();
- });
- }
- },
- render: function() {
- if (this.textBuffer.length === 0) {
- return;
- }
- var textNode = document.createTextNode(this.textBuffer.join(''));
- this.textBuffer = [];
- this.$.console.appendChild(textNode);
- var scrollTop = this.scrollTop;
- this.scrolling = scrollTop > 0;
- if (this.autoScroll) {
- this.scrollTop = this.scrollHeight;
- }
- },
- /*
- * Appends text to the console
- * @param {string} text Text to add
- */
- addText: function(text) {
- this.textBuffer.push(text);
- }
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/panic/component.css b/examples/pipetobrowser/browser/pipe-viewers/builtin/console/panic/component.css
deleted file mode 100644
index 2a054d8..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/panic/component.css
+++ /dev/null
@@ -1,46 +0,0 @@
-:host {
- background-color: #000000;
- height: 100%;
- display: block;
- overflow: auto;
-}
-
-pre {
- margin: 0;
- padding: 0.5em;
-
- font-family: Fixed, monospace;
- line-height: 1.2em;
- word-break: break-word;
-
- color: #ffffff;
-}
-
-.auto-scroll {
- position: fixed;
- right: 40px;
- bottom: 0;
- opacity: 0.8;
- padding: 0.8em;
- background-color: #ffeb3b;
- z-index: 1;
-}
-
-paper-input {
- position: fixed;
- right: 50px;
- color: #cccccc;
- background-color: #ffffff;
- z-index: 1;
-}
-
-core-item.showHide {
- background-color: #ff0000;
- color: #ffffff;
- cursor: pointer;
- margin: 5px;
-}
-
-.yellowback {
- background-color: #666600;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/panic/component.html b/examples/pipetobrowser/browser/pipe-viewers/builtin/console/panic/component.html
deleted file mode 100644
index 6669be4..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/panic/component.html
+++ /dev/null
@@ -1,122 +0,0 @@
-<link rel="import" href="../../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../../third-party/paper-checkbox/paper-checkbox.html">
-
-<polymer-element name="p2b-plugin-console-panic">
- <template>
- <link rel="stylesheet" href="component.css">
- <link rel="stylesheet" href="../../../../libs/css/common-style.css">
- <div title="Auto Scroll" class="auto-scroll {{ {hidden : !scrolling} | tokenList}}">
- <paper-checkbox checked="{{autoScroll}}" label="Auto Scroll" id="autoscroll"></paper-checkbox>
- </div>
- <paper-input id="filter" label="Filter by keyword..."></paper-input>
- <pre id="console"></pre>
- </template>
- <script>
- Polymer('p2b-plugin-console-panic', {
- ready: function() {
- this.autoScroll = true;
-
- // Prepare our current container and current line
- this.startNewContainer(false);
- this.startNewLine();
-
- this.$.filter.addEventListener('input', this.filterAllText.bind(this), false);
- },
- /*
- * Scrolls the plugin console, if this.autoScroll is true
- */
- scrollAuto: function() {
- // Scroll if we need to.
- var scrollTop = this.scrollTop;
- this.scrolling = scrollTop > 0;
- if (this.autoScroll) {
- this.scrollTop = this.scrollHeight;
- }
- },
- /*
- * Turns off autoscrolling
- */
- scrollOff: function() {
- this.autoScroll = false;
- },
- /*
- * Create a new container div for lines of text
- * @param {boolean} whether or not the container should start hidden or not
- * @param {string} (optional) the control button's name for toggling hidden on this container.
- */
- startNewContainer: function(isCollapsed, withToggleButtonName) {
- this.container = document.createElement('div');
-
- // If the container should be collapsed, hide it.
- if (isCollapsed) {
- this.container.classList.toggle('hidden');
- }
-
- if (withToggleButtonName) {
- // This button controls whether to show/hide the container.
- var control = document.createElement('core-item');
- control.label = withToggleButtonName;
- control.classList.add("showHide");
- control.icon = "swap-vert";
- var container = this.container;
- control.addEventListener(
- 'click',
- function toggle() {
- container.classList.toggle('hidden');
- },
- false
- );
- this.$.console.appendChild(control);
- }
-
- this.$.console.appendChild(this.container);
- },
- /*
- * Create a new div for the current line of text. Scroll if necessary.
- */
- startNewLine: function() {
- this.line = document.createElement('div');
- this.line.classList.add('line');
- this.container.appendChild(this.line);
- this.scrollAuto();
- },
- /*
- * Add a <br> element to the container. Scroll if necessary.
- */
- addLineBreak: function() {
- this.container.appendChild(document.createElement('br'));
- this.scrollAuto();
- },
- /*
- * Append text to the current line of text.
- * Additionally, filter this line since it was modified.
- * @param {string} the text to be appended
- */
- addText: function(text) {
- this.line.appendChild(document.createTextNode(text));
- this.filter(this.line);
- },
- /*
- * All elements with class 'line' are filtered.
- */
- filterAllText: function() {
- var elems = this.$.console.getElementsByClassName('line');
- for (var i = 0; i < elems.length; i++) {
- this.filter(elems[i]);
- }
- },
- /*
- * If the given element's text contains the filter's input value,
- * a yellow background is assigned. Otherwise, it is removed.
- * @param {div} the given element whose background will be modified
- */
- filter: function(elem) {
- var value = this.$.filter.inputValue;
-
- // Force add/remove the yellowback class depending on if the element has the value or not. Don't highlight if the value is empty.
- var shouldHighlight = (value && elem.textContent.indexOf(value) >= 0);
- elem.classList.toggle('yellowback', shouldHighlight);
- }
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/panic/plugin.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/console/panic/plugin.js
deleted file mode 100644
index 256f631..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/panic/plugin.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Console is a Pipe Viewer that displays a text stream as unformatted text
- * @tutorial echo "Hello World" | p2b google/p2b/[name]/console/panic
- * @fileoverview
- */
-
-import { View } from 'view';
-import { PipeViewer } from 'pipe-viewer';
-
-class ConsolePanicPipeViewer extends PipeViewer {
- get name() {
- return 'console-panic';
- }
-
- play(stream) {
- var consoleView = document.createElement('p2b-plugin-console-panic');
-
- // Internal stream variables
- var panicked = false;
- var lastPiece = "";
-
- // read data as UTF8
- stream.setEncoding('utf8');
- stream.on('data', (buf) => {
- // Always split the incoming text by newline.
- var pieces = buf.toString().split("\n");
- for (var i = 0; i < pieces.length; i++) {
- var piece = pieces[i];
-
- // flags for the status of the current line
- var goroutine = (piece.search(/goroutine \d+ \[\D+\]:/) == 0);
- var startOfLine = (i != 0 || lastPiece == "");
-
- if (goroutine && startOfLine) {
- // We spotted a goroutine at the start of a line, so create a new container.
- consoleView.startNewContainer(panicked, piece);
-
- // Stop scrolling if we've already panicked.
- // This will focus the element on the first crashed goroutine.
- if (panicked) {
- consoleView.scrollAuto();
- consoleView.scrollOff();
- }
- panicked = true;
-
- // We also need a new line for our new container.
- consoleView.startNewLine();
- } else if (i > 0) {
- // These lines followed a \n in the buffer and thus should go on a new line.
- if (lastPiece == "") {
- // The previous line was empty; empty div's have 0 height.
- // We need to add a <br /> to print the linebreak properly.
- consoleView.addLineBreak();
- }
- consoleView.startNewLine();
- }
-
- // Add the relevant text.
- consoleView.addText(piece);
- lastPiece = piece;
- }
- });
-
- return new View(consoleView);
- }
-}
-
-export default ConsolePanicPipeViewer;
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/plugin.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/console/plugin.js
deleted file mode 100644
index 9c27f58..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/console/plugin.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Console is a Pipe Viewer that displays a text stream as unformatted text
- * @tutorial echo "Hello World" | p2b google/p2b/[name]/console
- * @fileoverview
- */
-
-import { View } from 'view';
-import { PipeViewer } from 'pipe-viewer';
-
-class ConsolePipeViewer extends PipeViewer {
- get name() {
- return 'console';
- }
-
- play(stream) {
- var consoleView = document.createElement('p2b-plugin-console');
-
- // read data as UTF8
- stream.setEncoding('utf8');
- stream.on('data', (buf) => {
- var textVal = buf.toString();
- consoleView.addText(textVal);
- });
-
- return new View(consoleView);
- }
-}
-
-export default ConsolePipeViewer;
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/dev/null/plugin.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/dev/null/plugin.js
deleted file mode 100644
index 06546dc..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/dev/null/plugin.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * dev/null simply consumes the stream without taking any action on the data
- * or keeping it in memory
- * @tutorial echo "To the black hole!" | p2b google/p2b/[name]/dev/null
- * @fileoverview
- */
-
-import { View } from 'view';
-import { PipeViewer } from 'pipe-viewer';
-
-class DevNullPipeViewer extends PipeViewer {
- get name() {
- return 'dev/null';
- }
-
- play(stream) {
-
- var blackhole = document.createElement('p2b-blackhole');
- blackhole.start();
-
- stream.on('data', () => {
- // consume the stream
- });
-
- stream.on('end', () => {
- blackhole.stop();
- });
-
- return new View(blackhole);
- }
-}
-
-export default DevNullPipeViewer;
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/dev/null/text/plugin.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/dev/null/text/plugin.js
deleted file mode 100644
index 3a37f15..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/dev/null/text/plugin.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * similar to dev/null, it consumes the stream without keeping it in memory but
- * it tried to decode the steaming bytes as UTF-8 string first
- * @tutorial echo "To the black hole!" | p2b google/p2b/[name]/dev/null/text
- * @fileoverview
- */
-
-import { View } from 'view';
-import { PipeViewer } from 'pipe-viewer';
-import { redirectPlay } from 'pipe-viewer-delegation';
-
-class DevNullTextPipeViewer extends PipeViewer {
- get name() {
- return 'dev/null/text';
- }
-
- play(stream) {
-
- stream.setEncoding('utf8');
-
- stream.on('data', (buf) => {
- // consume the stream as string
- var text = buf.toString();
- });
-
- // redirect to regular dev/null to play the stream
- var delegatedView = redirectPlay('dev/null', stream);
-
- return delegatedView;
- }
-}
-
-export default DevNullTextPipeViewer;
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/component.css b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/component.css
deleted file mode 100644
index 99617a1..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/component.css
+++ /dev/null
@@ -1,29 +0,0 @@
-::shadow /deep/ .state-icon.notstaged {
- fill: #f57c00;
-}
-
-::shadow /deep/ .state-icon.staged {
- fill: #689f38;
-}
-
-::shadow /deep/ .state-icon.conflicted {
- fill: #bf360c;
- -webkit-animation: blink 0.6s infinite alternate;
-}
-
-::shadow /deep/ .state-icon.untracked {
- fill: #bf360c;
-}
-
-::shadow /deep/ .state-icon.ignored {
- fill: #689f38;
-}
-
-::shadow /deep/ .action-icon {
- fill: #91a7ff;
-}
-
-::shadow /deep/ .file-parent {
- font-size: 0.8em;
- color: rgba(0,0,0,.54);
-}
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/component.html b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/component.html
deleted file mode 100644
index a4db818..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/component.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<link rel="import" href="../../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../../third-party/core-icon/core-icon.html">
-<link rel="import" href="../../../../libs/ui-components/data-grid/grid/component.html">
-<link rel="import" href="../../../../libs/ui-components/data-grid/grid/column/component.html">
-<link rel="import" href="../../../../libs/ui-components/data-grid/filter/select/component.html">
-<link rel="import" href="../../../../libs/ui-components/data-grid/filter/select/item/component.html">
-<link rel="import" href="../../../../libs/ui-components/data-grid/filter/toggle/component.html">
-<link rel="import" href="../../../../libs/ui-components/data-grid/search/component.html">
-
-<polymer-element name="p2b-plugin-git-status">
- <template>
-
- <link rel="stylesheet" href="../../../../libs/css/common-style.css">
- <link rel="stylesheet" href="component.css">
-
- <p2b-grid id="grid" defaultSortKey="state" defaultSortAscending dataSource="{{ dataSource }}" summary="Data Grid displaying status of modified file for the git repository.">
-
- <!-- Search -->
- <p2b-grid-search label="Search Logs"></p2b-grid-search>
-
- <!-- State Filter (multiple allowed) -->
- <p2b-grid-filter-select multiple key="state" label="Show state">
- <p2b-grid-filter-select-item checked label="Staged" value="staged"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Not Staged" value="notstaged"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Conflicted" value="conflicted"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Untracked" value="untracked"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Ignored" value="ignored"></p2b-grid-filter-select-item>
- </p2b-grid-filter-select>
-
- <!-- Action Filter (multiple allowed) -->
- <p2b-grid-filter-select multiple key="action" label="Show actions">
- <p2b-grid-filter-select-item checked label="Added" value="added"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Deleted" value="deleted"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Modified" value="modified"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Renamed" value="renamed"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Copied" value="copied"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Unknown" value="unknown"></p2b-grid-filter-select-item>
- </p2b-grid-filter-select>
-
- <!-- Columns, sorting and cell templates -->
- <p2b-grid-column label="State" key="state" sortable flex="2" priority="2" >
- <template>
- <core-icon class="state-icon {{ item.state }}" icon="{{ item.stateIcon }}" title="{{item.state}}"></core-icon>
- <span moreInfoOnly style="vertical-align:middle">{{item.state}}</span>
- </template>
- </p2b-grid-column>
- <p2b-grid-column label="Action" key="action" sortable flex="2" priority="3" >
- <template>
- <core-icon class="action-icon {{ item.action }}" icon="{{ item.actionIcon }}" title="{{item.action}}"></core-icon>
- <span moreInfoOnly style="vertical-align:middle">{{item.action}}</span>
- </template>
- </p2b-grid-column>
- <p2b-grid-column label="File" key="filename" sortable primary flex="8" minFlex="5" priority="1" >
- <template>{{ item.filename }}
- <div class="file-parent" title="folder: {{item.fileParent}}">{{ item.fileParent }}</div>
- </template>
- </p2b-grid-column>
- <p2b-grid-column label="Summary" flex="7" minFlex="3" priority="4" >
- <template>{{ item.summary }}</template>
- </p2b-grid-column>
-
- </p2b-grid>
- </template>
- <script>
- Polymer('p2b-plugin-git-status', {
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/data-source.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/data-source.js
deleted file mode 100644
index 3e6a271..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/data-source.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Implement the data source which handles searching, filtering
- * and sorting of the git status items
- * @fileoverview
- */
-
-import { gitStatusSort } from './sorter';
-import { gitStatusSearch } from './searcher';
-import { gitStatusFilter } from './filterer';
-
-export class gitStatusDataSource {
- constructor(items) {
-
- /*
- * all items, unlimited buffer for now.
- * @private
- */
- this.allItems = items;
- }
-
- /*
- * Implements the fetch method expected by the grid components.
- * handles searching, filtering and sorting of the data.
- * search, sort and filters are provided by the grid control whenever they are
- * changed by the user.
- * DataSource is called automatically by the grid when user interacts with the component
- * Grid does some batching of user actions and only calls fetch when needed.
- * keys provided for sort and filters correspond to keys set in the markup
- * when constructing the grid.
- * @param {object} search search{key<string>} current search keyword
- * @param {object} sort sort{key<string>, ascending<bool>} current sort key and direction
- * @param {map} filters map{key<string>, values<Array>} Map of filter keys to currently selected filter values
- * @return {Array<object>} Returns an array of filtered sorted results of the items.
- */
- fetch(search, sort, filters) {
-
- var filteredSortedItems = this.allItems.
- filter((item) => {
- return gitStatusFilter(item, filters);
- }).
- filter((item) => {
- return gitStatusSearch(item, search.keyword);
- }).
- sort((item1, item2) => {
- return gitStatusSort(item1, item2, sort.key, sort.ascending);
- });
-
- return filteredSortedItems;
-
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/filterer.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/filterer.js
deleted file mode 100644
index 4976e66..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/filterer.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Returns whether the given git status items matches the map of filters.
- * @param {Object} item A single git status item as defined by parser.item
- * @param {map} filters Map of keys to selected filter values as defined
- * when constructing the filters in the grid components.
- * e.g. filters:{'state':['staged'], 'action':['added','modified']}
- * @return {boolean} Whether the item satisfies ALL of the given filters.
- */
-export function gitStatusFilter(item, filters) {
- if (Object.keys(filters).length === 0) {
- return true;
- }
-
- for (var key in filters) {
- var isMatch = applyFilter(item, key, filters[key]);
- // we AND all the filters, short-circuit for early termination
- if (!isMatch) {
- return false;
- }
- }
-
- // matches all filters
- return true;
-};
-
-/*
- * Returns whether the given git status item matches a single filter
- * @param {Object} item A single git status item as defined by parser.item
- * @param {string} key filter key e.g. 'state'
- * @param {string} value filter value e.g. '['staged','untracked']
- * @return {boolean} Whether the item satisfies then the given filter key value pair
- * @private
- */
-function applyFilter(item, key, value) {
- switch (key) {
- case 'state':
- case 'action':
- return value.indexOf(item[key]) >= 0;
- default:
- // ignore unknown filters
- return true;
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/parser.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/parser.js
deleted file mode 100644
index b9e2c50..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/parser.js
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Parse utilities for git statuses
- * @see http://git-scm.com/docs/git-status#_short_format
- * @fileoverview
- */
-
-/*
- * Parses a single line of text produced by git status --short command
- * into an structured object representing the status of that file.
- * git-status short format is XY PATH1 -> PATH2
- * Please see documentation at:
- * http://git-scm.com/docs/git-status#_short_format
- * for details of the format and meaning of each component/
- * @param {string} gitStatusLine A single line of text produced
- * by git status --short command
- * @return {parser.item} A parsed object containing status, file path, etc..
- */
-export function parse(gitStatusLine) {
-
- var validGitStatusRegex = /^[\sMADRCU?!]{2}[\s]{1}.+/
- if(!validGitStatusRegex.test(gitStatusLine)) {
- throw new Error('Invalid git status line format. ' + gitStatusLine +
- ' does not match XY PATH1 -> PATH2 format where -> PATH2 is optional ' +
- ' and X and Y should be one of [<space>MADRCU?!].' +
- ' Please ensure you are using --short flag when running git status');
- }
-
- // X is status for working tree
- // Y is status for the index
- var X = gitStatusLine.substr(0,1);
- var Y = gitStatusLine.substr(1,1);
-
- // files
- var files = gitStatusLine.substring(3).split('->');
- var file = files[0];
- var oldFile = null;
- // we may have oldFile -> file for cases like rename and copy
- if (files.length == 2) {
- file = files[1];
- oldFile = files[0];
- }
-
- var fileStateInfo = getFileState(X, Y);
- var fileAction = getFileAction(X, Y , fileStateInfo.state);
- var summary = fileStateInfo.summary + ', file ' + fileAction;
- if(oldFile) {
- summary += ' to ' + oldFile;
- }
-
- return new item(
- fileAction,
- fileStateInfo.state,
- file,
- summary
- );
-}
-
-/*
- * A structure representing the status of a git file.
- * @param {string} action, one of added, deleted, renamed, copied, modified, unknown
- * @param {string} state, one staged, notstaged, conflicted, untracked, ignored
- * @param {string} file filename and path
- * @param {string} summary A summary text for what these states mean
- * @class
- * @private
- */
-class item {
- constructor(action, state, file, summary) {
- this.action = action;
- this.state = state;
- this.file = file;
- this.summary = summary;
- }
-}
-
-var actionCodes = {
- 'M': 'modified',
- 'U': 'modified',
- 'A': 'added',
- 'D': 'deleted',
- 'R': 'renamed',
- 'C': 'copied',
- '?': 'unknown',
- '!': 'unknown'
-}
-/*
- * Returns the action performed on the file, one of added, deleted, renamed,
- * copied, modified, unknown
- * @private
- */
-function getFileAction(X, Y, fileState) {
- var codeToUse = X;
- if (fileState === 'notstaged') {
- codeToUse = Y;
- }
-
- return actionCodes[codeToUse];
-}
-
-/*
- * Returns the git state of file, staged, notstaged, conflicted, untracked, ignored
- * @private
- */
-function getFileState(X, Y) {
-
- // check for conflict, the following combinations represent a conflict
- // ------------------------------------------------
- // D D unmerged, both deleted
- // A U unmerged, added by us
- // U D unmerged, deleted by them
- // U A unmerged, added by them
- // D U unmerged, deleted by us
- // A A unmerged, both added
- // U U unmerged, both modified
- // -------------------------------------------------
- var conflictSummary = null;
- if(X === 'D' && Y == 'D') {
- conflictSummary = 'Conflicted, both deleted';
- } else if(X === 'A' && Y === 'U') {
- conflictSummary = 'Conflicted, added by us';
- } else if(X === 'U' && Y === 'D') {
- conflictSummary = 'Conflicted, deleted by them';
- } else if(X === 'U' && Y === 'A') {
- conflictSummary = 'Conflicted, added by them';
- } else if(X === 'D' && Y === 'U') {
- conflictSummary = 'Conflicted, deleted by us';
- } else if(X === 'A' && Y === 'A') {
- conflictSummary = 'Conflicted, both added';
- } else if(X === 'U' && Y === 'U') {
- conflictSummary = 'Conflicted, both modified';
- }
-
- if (conflictSummary !== null) {
- return {
- state: 'conflicted',
- summary: conflictSummary
- }
- }
-
- // check for untracked
- if (X === '?' || Y === '?') {
- return {
- state:'untracked',
- summary: 'Untracked file'
- }
- }
-
- // check for ignored
- if (X === '!' || Y === '!') {
- return {
- state: 'ignored',
- summary: 'Ignored file'
- }
- }
-
- // check for notstaged
- if (Y !== ' ') {
- return {
- state:'notstaged',
- summary: 'Not staged for commit'
- }
- } else {
- // otherwise staged
- return {
- state: 'staged',
- summary: 'Staged for commit'
- }
- }
-}
-
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/plugin.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/plugin.js
deleted file mode 100644
index 11583c5..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/plugin.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * git/status is a Pipe Viewer that displays output of "git status --short"
- * in a graphical grid.
- * Only supported with Git's --short flag.
- * @tutorial git status --short | p2b google/p2b/[name]/git/status
- * @fileoverview
- */
-import { View } from 'view';
-import { PipeViewer } from 'pipe-viewer';
-import { streamUtil } from 'stream-helpers';
-import { Logger } from 'logger';
-import { parse } from './parser';
-import { gitStatusDataSource } from './data-source';
-
-var log = new Logger('pipe-viewers/builtin/git/status');
-
-class GitStatusPipeViewer extends PipeViewer {
- get name() {
- return 'git/status';
- }
-
- play(stream) {
- stream.setEncoding('utf8');
-
- // split by new line
- stream = stream.pipe(streamUtil.split(/\r?\n/));
-
- // parse the git status items
- stream = stream.pipe(streamUtil.map((line, cb) => {
- if (line.trim() === '') {
- // eliminate the item
- cb();
- return;
- }
- var item;
- try {
- item = parse(line);
- } catch(e) {
- log.debug(e);
- }
- if (item) {
- addAdditionalUIProperties(item);
- cb(null, item);
- } else {
- // eliminate the item
- cb();
- }
- }));
-
- // we return a view promise instead of a view since we want to wait
- // until all items arrive before showing the data.
- var viewPromise = new Promise(function(resolve,reject) {
- // write into an array when stream is done return the UI component
- stream.pipe(streamUtil.writeArray((err, items) => {
- if (err) {
- reject(err);
- } else {
- var statusView = document.createElement('p2b-plugin-git-status');
- statusView.dataSource = new gitStatusDataSource(items);
- resolve(new View(statusView));
- }
- }));
- });
-
- return viewPromise;
- }
-}
-
-/*
- * Adds additional UI specific properties to the item
- * @private
- */
-function addAdditionalUIProperties(item) {
- addActionIconProperty(item);
- addStateIconProperty(item);
- addFileNameFileParentProperty(item);
-}
-
-/*
- * Adds an icon property to the item specifying what icon to display
- * based on state
- * @private
- */
-function addStateIconProperty(item) {
- var iconName;
- switch (item.state) {
- case 'staged':
- iconName = 'check-circle';
- break;
- case 'notstaged':
- iconName = 'warning';
- break;
- case 'conflicted':
- iconName = 'block';
- break;
- case 'untracked':
- iconName = 'error';
- break;
- case 'ignored':
- iconName = 'visibility-off';
- break;
- }
-
- item.stateIcon = iconName;
-}
-
-/*
- * Adds an icon property to the item specifying what icon to display
- * based on action
- * @private
- */
-function addActionIconProperty(item) {
- var iconName;
- switch (item.action) {
- case 'added':
- iconName = 'add';
- break;
- case 'deleted':
- iconName = 'clear';
- break;
- case 'modified':
- iconName = 'translate';
- break;
- case 'renamed':
- iconName = 'swap-horiz';
- break;
- case 'copied':
- iconName = 'content-copy';
- break;
- case 'unknown':
- iconName = 'remove';
- break;
- }
-
- item.actionIcon = iconName;
-}
-
-/*
- * Splits file into filename and fileParent
- * @private
- */
-function addFileNameFileParentProperty(item) {
-
- var filename = item.file;
- var fileParent = "./";
-
- var slashIndex = item.file.lastIndexOf('/');
-
- if (slashIndex > 0) {
- filename = item.file.substr(slashIndex + 1);
- fileParent = item.file.substring(0, slashIndex);
- }
-
- item.filename = filename;
- item.fileParent = fileParent;
-}
-
-export default GitStatusPipeViewer;
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/searcher.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/searcher.js
deleted file mode 100644
index 57e8a01..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/searcher.js
+++ /dev/null
@@ -1,12 +0,0 @@
-export function gitStatusSearch(item, keyword) {
- if (!keyword) {
- return true;
- }
-
- // we only search file
- if (item.file.indexOf(keyword) >= 0) {
- return true
- }
-
- return false;
-};
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/sorter.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/sorter.js
deleted file mode 100644
index 9dec432..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/git/status/sorter.js
+++ /dev/null
@@ -1,41 +0,0 @@
-var stateSortPriority = {
- 'conflicted' : 1,
- 'untracked' : 2,
- 'notstaged' : 3,
- 'staged': 4,
- 'ignored': 5
-}
-
-var actionSortPriority = {
- 'added' : 1,
- 'deleted' : 2,
- 'modified' : 3,
- 'renamed': 4,
- 'copied': 5,
- 'unknown': 6
-}
-
-export function gitStatusSort(item1, item2, key, ascending) {
- var first = item1[key];
- var second = item2[key];
- if (!ascending) {
- first = item2[key];
- second = item1[key];
- }
-
- if (key === 'state') {
- first = stateSortPriority[first];
- second = stateSortPriority[second];
- }
-
- if (key === 'action') {
- first = actionSortPriority[first];
- second = actionSortPriority[second];
- }
-
- if (typeof first === 'string') {
- return first.localeCompare(second);
- } else {
- return first - second;
- }
-};
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/image/plugin.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/image/plugin.js
deleted file mode 100644
index 8564147..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/image/plugin.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Image is a Pipe Viewer that displays an image
- * @tutorial cat image.jpg | p2b google/p2b/[name]/image
- * @fileoverview
- */
-
-import { View } from 'view';
-import { PipeViewer } from 'pipe-viewer';
-
-class ImagePipeViewer extends PipeViewer {
- get name() {
- return 'image';
- }
-
- play(stream) {
- var viewPromise = new Promise(function(resolve,reject) {
- var blobParts = [];
- stream.on('data', (chunk) => {
- blobParts.push(new Uint8Array(chunk));
- });
-
- stream.on('end', () => {
- var image = document.createElement('img');
- image.style.width = '100%';
- var url = URL.createObjectURL(new Blob(blobParts));
- image.src = url;
- resolve(new View(image));
- });
- });
-
- return viewPromise;
- }
-}
-
-export default ImagePipeViewer;
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/component.css b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/component.css
deleted file mode 100644
index cfbfeee..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/component.css
+++ /dev/null
@@ -1,29 +0,0 @@
-::shadow /deep/ .line-number::before {
- content: '#';
-}
-::shadow /deep/ .line-number {
- color: rgb(51, 103, 214);
- margin-left: 0.1em;
- font-size: 0.8em;
-}
-
-::shadow /deep/ .message-text {
- word-break: break-word;
-}
-
-::shadow /deep/ .level-icon.error {
- fill: #e51c23;
-}
-
-::shadow /deep/ .level-icon.warning {
- fill: #f57c00;
-}
-
-::shadow /deep/ .level-icon.info {
- fill: #689f38;
-}
-
-::shadow /deep/ .level-icon.fatal {
- fill: #bf360c;
- -webkit-animation: blink 0.6s infinite alternate;
-}
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/component.html b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/component.html
deleted file mode 100644
index 3a70a5c..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/component.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<link rel="import" href="../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../third-party/core-icon/core-icon.html">
-<link rel="import" href="../../../libs/ui-components/data-grid/grid/component.html">
-<link rel="import" href="../../../libs/ui-components/data-grid/grid/column/component.html">
-<link rel="import" href="../../../libs/ui-components/data-grid/filter/select/component.html">
-<link rel="import" href="../../../libs/ui-components/data-grid/filter/select/item/component.html">
-<link rel="import" href="../../../libs/ui-components/data-grid/filter/toggle/component.html">
-<link rel="import" href="../../../libs/ui-components/data-grid/search/component.html">
-
-<polymer-element name="p2b-plugin-vlog">
- <template>
- <link rel="stylesheet" href="../../../libs/css/common-style.css">
- <link rel="stylesheet" href="component.css">
-
- <p2b-grid id="grid" defaultSortKey="date" dataSource="{{ dataSource }}" summary="Data Grid displaying veyron log items in a tabular format with filters and search options.">
-
- <!-- Search -->
- <p2b-grid-search label="Search Logs"></p2b-grid-search>
-
- <!-- Filter to select log level (multiple allowed) -->
- <p2b-grid-filter-select multiple key="level" label="Show levels">
- <p2b-grid-filter-select-item checked label="Fatal" value="fatal"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Error" value="error"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Warning" value="warning"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item checked label="Info" value="info"></p2b-grid-filter-select-item>
- </p2b-grid-filter-select>
-
- <!-- Filter to select date range -->
- <p2b-grid-filter-select key="date" label="Logs since">
- <p2b-grid-filter-select-item checked label="Any time" value="all"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item label="Past 1 hour" value="1"></p2b-grid-filter-select-item>
- <p2b-grid-filter-select-item label="Past 24 hours" value="24"></p2b-grid-filter-select-item>
- </p2b-grid-filter-select>
-
- <!-- Toggle to allow one to pause the display of incoming logs -->
- <p2b-grid-filter-toggle key="autorefresh" label="Live Refresh" checked></p2b-grid-filter-toggle>
-
- <!-- Columns, sorting and cell templates -->
- <p2b-grid-column label="Level" key="level" sortable flex="2" priority="2" >
- <template>
- <core-icon class="level-icon {{ item.level }}" icon="{{ item.icon }}" title="{{item.level}}"></core-icon>
- <span moreInfoOnly style="vertical-align:middle">{{item.level}}</span>
- </template>
- </p2b-grid-column>
- <p2b-grid-column label="File" key="file" sortable flex="4" minFlex="2" priority="4" >
- <template>{{ item.file }}<span class="line-number">{{ item.fileLine }}</span></template>
- </p2b-grid-column>
- <p2b-grid-column label="Message" key="message" primary flex="8" minFlex="5" priority="1" >
- <template><div class="message-text">{{ item.message }}</div></template>
- </p2b-grid-column>
- <p2b-grid-column label="Date" key="date" sortable flex="4" minFlex="3" priority="3">
- <template>
- <abbr gridOnly title="{{item.date}}">{{ item.formattedDate }}</abbr>
- <span moreInfoOnly>{{item.date}}</span>
- </template>
-
- </p2b-grid-column>
- <p2b-grid-column label="Threadid" key="threadid" sortable flex="0" priority="5">
- <template>{{ item.threadId }}</template>
- </p2b-grid-column>
-
- </p2b-grid>
- </template>
-
- <script>
- Polymer('p2b-plugin-vlog', {
- refreshGrid: function() {
- this.$.grid.refresh();
- }
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/data-source.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/data-source.js
deleted file mode 100644
index be602c0..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/data-source.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Implement the data source which handles parsing the stream, searching, filtering
- * and sorting of the vLog items.
- * @fileoverview
- */
-import { parse } from './parser';
-import { vLogSort } from './sorter';
-import { vLogSearch } from './searcher';
-import { vLogFilter } from './filterer';
-
-export class vLogDataSource {
- constructor(stream, onNewItem, onError) {
-
- /*
- * all logs, unlimited buffer for now.
- * @private
- */
- this.allLogItems = [];
-
- /*
- * Raw stream of log data
- * @private
- */
- this.stream = stream;
-
- stream.on('data', (line) => {
- if (line.trim() === '') {
- return;
- }
- var logItem = null;
- // try to parse and display as much as we can.
- try {
- logItem = parse(line);
- } catch (e) {
- if (onError) {
- onError(e);
- }
- }
-
- if (logItem) {
- this.allLogItems.push(logItem);
- if (onNewItem) {
- onNewItem(logItem);
- }
- }
- });
-
- }
-
- /*
- * Implements the fetch method expected by the grid components.
- * handles parsing the stream, searching, filtering and sorting of the data.
- * search, sort and filters are provided by the grid control whenever they are
- * changed by the user.
- * DataSource is called automatically by the grid when user interacts with the component
- * Grid does some batching of user actions and only calls fetch when needed.
- * keys provided for sort and filters correspond to keys set in the markup
- * when constructing the grid.
- * @param {object} search search{key<string>} current search keyword
- * @param {object} sort sort{key<string>, ascending<bool>} current sort key and direction
- * @param {map} filters map{key<string>, values<Array>} Map of filter keys to currently selected filter values
- * @return {Array<object>} Returns an array of filtered sorted results of the items.
- */
- fetch(search, sort, filters) {
-
- var filteredSortedItems = this.allLogItems.
- filter((item) => {
- return vLogFilter(item, filters);
- }).
- filter((item) => {
- return vLogSearch(item, search.keyword);
- }).
- sort((item1, item2) => {
- return vLogSort(item1, item2, sort.key, sort.ascending);
- });
-
- // pause or resume the stream when auto-refresh filter changes
- if (filters['autorefresh'] && this.stream.paused) {
- this.stream.resume();
- }
- if (!filters['autorefresh'] && !this.stream.paused) {
- this.stream.pause();
- }
-
- return filteredSortedItems;
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/filterer.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/filterer.js
deleted file mode 100644
index e40ebb0..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/filterer.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Returns whether the given vLogItem matches the map of filters.
- * @param {Object} item A single veyron log item as defined by parser.item
- * @param {map} filters Map of keys to selected filter values as defined
- * when constructing the filters in the grid components.
- * e.g. filters:{'date':'all', 'levels':['info','warning']}
- * @return {boolean} Whether the item satisfies ALL of the given filters.
- */
-export function vLogFilter(item, filters) {
- if (Object.keys(filters).length === 0) {
- return true;
- }
-
- for (var key in filters) {
- var isMatch = applyFilter(item, key, filters[key]);
- // we AND all the filters, short-circuit for early termination
- if (!isMatch) {
- return false;
- }
- }
-
- // matches all filters
- return true;
-};
-
-/*
- * Returns whether the given vLogItem matches a single filter
- * @param {Object} item A single veyron log item as defined by parser.item
- * @param {string} key filter key e.g. 'date'
- * @param {string} value filter value e.g. 'all'
- * @return {boolean} Whether the item satisfies then the given filter key value pair
- * @private
- */
-function applyFilter(item, key, value) {
- switch (key) {
- case 'date':
- return filterDate(item, value);
- case 'level':
- return filterLevel(item, value);
- default:
- // ignore unknown filters
- return true;
- }
-}
-
-/*
- * Returns whether item's date satisfies the date filter
- * @param {Object} item A single veyron log item as defined by parser.item
- * @param {string} since One of 'all', '1' or '24'. for Anytime, past one hour, past 24 hours.
- * @return {boolean} whether item's date satisfies the date filter
- * @private
- */
-function filterDate(item, since) {
- if (since === 'all') {
- return true;
- } else {
- var hours = parseInt(since);
- var targetDate = new Date();
- targetDate.setHours(targetDate.getHours() - hours);
- return item.date > targetDate;
- }
-}
-
-/*
- * Returns whether item's level is one of the given values
- * @param {Object} item A single veyron log item as defined by parser.item
- * @param {Array<string>} levels Array of level values e.g. ['info','warning']
- * @return {boolean} whether item's level is one of the given values
- * @private
- */
-function filterLevel(item, levels) {
- return levels.indexOf(item.level) >= 0;
-}
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/parser.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/parser.js
deleted file mode 100644
index d28e108..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/parser.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Parse utilities for veyron logs
- * @fileoverview
- */
-
-/*
- * Parses a single line of text produced by veyron logger
- * into an structured object representing it.
- * Log lines have this form:
- * Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
- * where the fields are defined as follows:
- * L A single character, representing the log level (eg 'I' for INFO)
- * mm The month (zero padded; ie May is '05')
- * dd The day (zero padded)
- * hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds
- * threadid The space-padded thread ID as returned by GetTID()
- * file The file name
- * line The line number
- * msg The user-supplied message
- * @param {string} vlogLine A single line of veyron log
- * @return {parser.item} A parsed object containing log level, date, file,
- * line number, thread id and message.
- */
-export function parse(vlogLine) {
-
- var validLogLineRegEx = /^([IWEF])(\d{2})(\d{2})\s(\d{2}:\d{2}:\d{2}\.\d+)\s(\d+)\s(.*):(\d+)]\s+(.*)$/
- var logParts = vlogLine.match(validLogLineRegEx);
- if (!logParts || logParts.length != 8 + 1) { // 8 parts + 1 whole match
- throw new Error('Invalid vlog line format. ' + vlogLine +
- ' Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg.. pattern');
- }
-
- var L = logParts[1];
- var month = logParts[2];
- var day = logParts[3];
- var time = logParts[4];
- var treadId = parseInt(logParts[5]);
- var file = logParts[6];
- var fileLine = parseInt(logParts[7]);
- var message = logParts[8];
-
- var now = new Date();
- var year = now.getFullYear();
- var thisMonth = now.getMonth() + 1; // JS months are 0-11
- // Year flip edge case, if log month > this month, we assume log line is from previous year
- if (parseInt(month) > thisMonth) {
- year--;
- }
-
- var date = new Date(year + '-' + month + '-' + day + ' ' + time);
-
- return new item(
- levelCodes[L],
- date,
- treadId,
- file,
- fileLine,
- message
- );
-}
-
-var levelCodes = {
- 'I': 'info',
- 'W': 'warning',
- 'E': 'error',
- 'F': 'fatal'
-}
-
-/*
- * A structure representing a veyron log item
- * @param {string} level, one of info, warning, error, fatal
- * @param {date} date, The date and time of the log item
- * @param {integer} threadId The thread ID as returned by GetTID()
- * @param {string} file The file name
- * @param {integer} fileLine The file line number
- * @param {string} message The user-supplied message
- * @class
- * @private
- */
-class item {
- constructor(level, date, threadId, file, fileLine, message) {
- this.level = level;
- this.date = date;
- this.threadId = threadId;
- this.file = file;
- this.fileLine = fileLine;
- this.message = message;
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/plugin.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/plugin.js
deleted file mode 100644
index d011cfd..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/plugin.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * vlog is a Pipe Viewer that displays veyron logs in a graphical grid.
- * Please note that Veyron writes logs to stderr stream, in *nix systems 2>&1
- * can be used to redirect stderr to stdout which can be then piped to P2B.
- * @tutorial myVeyronServerd -v=3 2>&1 | p2b google/p2b/[name]/vlog
- * @tutorial cat logfile.txt | p2b google/p2b/[name]/vlog
- * @fileoverview
- */
-import { View } from 'view';
-import { PipeViewer } from 'pipe-viewer';
-import { streamUtil } from 'stream-helpers';
-import { formatDate } from 'formatting';
-import { Logger } from 'logger'
-import { vLogDataSource } from './data-source';
-
-var log = new Logger('pipe-viewers/builtin/vlog');
-
-class vLogPipeViewer extends PipeViewer {
- get name() {
- return 'vlog';
- }
-
- play(stream) {
- stream.setEncoding('utf8');
-
- var logView = document.createElement('p2b-plugin-vlog');
- var newData = true;
- var refreshGrid = function() {
- requestAnimationFrame(() => {
- if( newData ) {
- logView.refreshGrid();
- newData = false;
- }
- refreshGrid();
- });
- };
- refreshGrid();
-
- // split by new line
- stream = stream.pipe(streamUtil.split(/\r?\n/));
-
- // create a new data source from the stream and set it.
- logView.dataSource = new vLogDataSource(
- stream,
- function onNewItem(item) {
- newData = true;
- // add additional, UI related properties to the item
- addAdditionalUIProperties(item);
- },
- function onError(err) {
- log.debug(err);
- });
-
- return new View(logView);
- }
-}
-
-/*
- * Adds additional UI specific properties to the item
- * @private
- */
-function addAdditionalUIProperties(item) {
- addIconProperty(item);
- addFormattedDate(item);
-}
-
-/*
- * Adds an icon property to the item specifying what icon to display
- * based on log level
- * @private
- */
-function addIconProperty(item) {
- var iconName = 'info';
- switch (item.level) {
- case 'info':
- iconName = 'info-outline';
- break;
- case 'warning':
- iconName = 'warning';
- break;
- case 'error':
- iconName = 'info';
- break;
- case 'fatal':
- iconName = 'block';
- break;
- }
-
- item.icon = iconName;
-}
-
-/*
- * Adds a human friendly date field
- * @private
- */
-function addFormattedDate(item) {
- item.formattedDate = formatDate(item.date);
-}
-
-export default vLogPipeViewer;
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/searcher.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/searcher.js
deleted file mode 100644
index 35e346c..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/searcher.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export function vLogSearch(logItem, keyword) {
- if (!keyword) {
- return true;
- }
-
- // we do a contains for message, file and threadId fields only
- if (logItem.message.indexOf(keyword) >= 0 ||
- logItem.file.indexOf(keyword) >= 0 ||
- logItem.threadId.toString().indexOf(keyword) >= 0) {
- return true
- }
-
- return false;
-};
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/sorter.js b/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/sorter.js
deleted file mode 100644
index 0e0a2db..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/builtin/vlog/sorter.js
+++ /dev/null
@@ -1,26 +0,0 @@
-var levelSortPriority = {
- 'fatal' : 1,
- 'error' : 2,
- 'warning' : 3,
- 'info': 4
-}
-
-export function vLogSort(item1, item2, key, ascending) {
- var first = item1[key];
- var second = item2[key];
- if (!ascending) {
- first = item2[key];
- second = item1[key];
- }
-
- if (key === 'level') {
- first = levelSortPriority[first];
- second = levelSortPriority[second];
- }
-
- if (typeof first === 'string') {
- return first.localeCompare(second);
- } else {
- return first - second;
- }
-};
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/manager.js b/examples/pipetobrowser/browser/pipe-viewers/manager.js
deleted file mode 100644
index 4c7dea0..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/manager.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Pipe viewer manager is used to load and get an instance of a pipe viewer
- * given its name.
- *
- * Manager handles on-demand loading and caching of pipe viewers.
- * @fileoverview
- */
-
-import { isAbsoulteUrl } from 'libs/utils/url'
-import { Logger } from 'libs/logs/logger'
-
-/*
- * Preload certain common builtin plugins.
- * Plugins are normally loaded on demand and this makes the initial bundle larger
- * but common plugins should be preloaded for better performance.
- * This is kind of a hack as it simply exposes a path to these
- * plugins so that build bundler finds them and bundles them with the reset of the app
- */
-import { default as plugin } from './builtin/vlog/plugin'
-import { default as plugin } from './builtin/image/plugin'
-import { default as plugin } from './builtin/console/plugin'
-
-var log = new Logger('pipe-viewer/manager');
-
-// cache loaded viewers
-var loadedPipeViewers = {};
-
-/*
- * Asynchronously loads and returns a PipeViewer plugin instance given its name.
- * @param {string} name Unique name of the viewer.
- * @return {Promise<PipeViewer>} pipe viewer for the given name
- */
-export function get(name) {
- if(isLoaded(name)) {
- return Promise.resolve(new loadedPipeViewers[name]());
- }
-
- return loadViewer(name).then((viewerClass) => {
- return new viewerClass();
- }).catch((e) => { return Promise.reject(e); });
-}
-
-/*
- * Tests whether the viewer plugin is already loaded or not.
- * @param {string} name Unique name of the viewer.
- * @return {string} Whether the viewer plugin is already loaded or not.
- *
- * @private
- */
-function isLoaded(name) {
- return loadedPipeViewers[name] !== undefined
-}
-
-/*
- * Registers a pipeViewer under a unique name and make it available to be called
- * @param {string} name Unique name of the viewer.
- * @return {Promise} when import completes.
- *
- * @private
- */
-function loadViewer(name) {
- log.debug('loading viewer:', name);
-
- var path = getPath(name);
- return System.import(path).then((module) => {
- var pipeViewerClass = module.default;
- loadedPipeViewers[name] = pipeViewerClass;
- return pipeViewerClass;
- }).catch((e) => {
- var errMessage = 'could not load viewer for: ' + name;
- log.debug(errMessage, e);
- return Promise.reject(new Error(errMessage));
- })
-}
-
-/*
- * Returns the path to a pipe viewer module location based on its name.
- * @param {string} name Unique name of the viewer.
- * @return {string} path to a pipe viewer module location.
- *
- * @private
- */
-function getPath(name) {
- if(isAbsoulteUrl(name)) {
- var encodedName = encodeURIComponent(name);
- System.paths[encodedName] = name;
- return encodedName;
- } else {
- return 'pipe-viewers/builtin/' + name + '/plugin';
- }
-}
diff --git a/examples/pipetobrowser/browser/pipe-viewers/pipe-viewer-delegation.js b/examples/pipetobrowser/browser/pipe-viewers/pipe-viewer-delegation.js
deleted file mode 100644
index 57122c6..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/pipe-viewer-delegation.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { get as getPipeViewer } from 'pipe-viewers/manager'
-
-/*
- * Allows a pipe-viewer plugin to delegate playing of a stream to another
- * pipe-viewer plugin.
- * Useful for cases where a plugin wants to simply do some transforms on the stream
- * and then have it be played by an existing plugin.
- * @param {string} pipeViewerName of the pipe-viewer to redirect to.
- * @param {Veyron.Stream} stream Stream of data to be redirected.
- * @return {Promise<View>} A promise of an View from the target pipe viewer, which can
- * be returned from the play() method of the caller plugin.
- */
-export function redirectPlay(pipeViewerName, stream) {
- return getPipeViewer(pipeViewerName).then((pipeViewer) => {
- return pipeViewer.play(stream);
- });
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/pipe-viewers/pipe-viewer.js b/examples/pipetobrowser/browser/pipe-viewers/pipe-viewer.js
deleted file mode 100644
index 738fb01..0000000
--- a/examples/pipetobrowser/browser/pipe-viewers/pipe-viewer.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Defines the interface expected to be implemented by any pipe viewer plugin.
- * A PipeViewer is an object that can render a stream of data.
- *
- * It has a unique name which is used to find the viewer plugin and direct
- * requests to it.
- *
- * It has a play function that will be called and supplied by a stream object.
- * play(stream) needs to return a View or promise of a View
- * that will be appended to the UI by the p2b framework.
- * If a promise, p2b UI will display a loading widget until promise is resolved.
- */
-export class PipeViewer {
-
- /*
- * @property {string} name Unique name of the viewer.
- */
- get name() {
- throw new Error('Abstract method. Must be implemented by subclasses');
- }
-
- /*
- * play() function is called by the p2b framework when a pipe request for the
- * this specific pipe viewer comes in.
- * @param {Veyron.Stream} stream Stream of data to be displayed.
- * @return {Promise<View>|{View}} a View or a promise of an
- * View that p2b can display.
- */
- play(stream) {
- throw new Error('Abstract method. Must be implemented by subclasses');
- }
-}
diff --git a/examples/pipetobrowser/browser/runtime/context.js b/examples/pipetobrowser/browser/runtime/context.js
deleted file mode 100644
index 0c92a81..0000000
--- a/examples/pipetobrowser/browser/runtime/context.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Holds references to runtime context but instead of one big context object
- * different context are exposed as their own object allowing other modules
- * just pick the context they need.
- * @fileoverview
- */
-
-import { PageView } from 'views/page/view'
-import { PipesView } from 'views/pipes/view'
-
-/*
- * Reference to the current page view object constructed by the application
- * @type {View}
- */
-export var page = new PageView();
-
-/*
- * Reference to the current pipes view object constructed by the application
- * @type {View}
- */
-export var pipesViewInstance = new PipesView();
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/services/pipe-to-browser-client.js b/examples/pipetobrowser/browser/services/pipe-to-browser-client.js
deleted file mode 100644
index 2af1a17..0000000
--- a/examples/pipetobrowser/browser/services/pipe-to-browser-client.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Implements a veyron client that can talk to a P2B service.
- * @fileoverview
- */
-import { Logger } from 'libs/logs/logger'
-import { config } from 'config/config'
-
-var log = new Logger('services/p2b-client');
-var veyron = new Veyron(config.veyron);
-
-/*
- * Pipes a stream of data to the P2B service identified
- * by the given veyron name.
- * @param {string} name Veyron name of the destination service
- * @param {Stream} Stream of data to pipe to it.
- * @return {Promise} Promise indicating if piping was successful or not
- */
-export function pipe(name, stream) {
- var client = veyron.newClient();
- return client.bindTo(name).then((remote) => {
- var remoteStream = remote.pipe().stream;
- stream.pipe(remoteStream);
- return Promise.resolve();
- });
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/services/pipe-to-browser-namespace.js b/examples/pipetobrowser/browser/services/pipe-to-browser-namespace.js
deleted file mode 100644
index 6910453..0000000
--- a/examples/pipetobrowser/browser/services/pipe-to-browser-namespace.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Implements a veyron client that talks to the namespace service and finds all
- * the P2B services that are available.
- * @fileoverview
- */
-import { Logger } from 'libs/logs/logger'
-import { config } from 'config/config'
-
-var log = new Logger('services/p2b-namespace');
-var veyron = new Veyron(config.veyron);
-var client = veyron.newClient();
-
-/*
- * Finds all the P2B services that are published by querying the namespace.
- * @return {Promise} Promise resolving to an array of names for all published
- * P2B services
- */
-export function getAll() {
- return client.bindTo(config.namespaceRoot).then((namespace) => {
- var globResult = namespace.glob('google/p2b/*');
- var p2bServices = [];
- globResult.stream.on('data', (p2bServiceName) => {
- p2bServices.push(p2bServiceName.name);
- });
-
- // wait until all the data arrives then return the collection
- return globResult.then(() => {
- return p2bServices;
- });
- });
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/services/pipe-to-browser-server.js b/examples/pipetobrowser/browser/services/pipe-to-browser-server.js
deleted file mode 100644
index ac4e0f4..0000000
--- a/examples/pipetobrowser/browser/services/pipe-to-browser-server.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Implements and publishes a Veyron service which accepts streaming RPC
- * requests and delegates the stream back to the provided pipeRequestHandler.
- * It also exposes the state of the service.
- * @fileoverview
- */
-import { Logger } from 'libs/logs/logger'
-import { config } from 'config/config'
-import { ByteObjectStreamAdapter } from 'libs/utils/byte-object-stream-adapter'
-import { StreamByteCounter } from 'libs/utils/stream-byte-counter'
-import { StreamCopy } from 'libs/utils/stream-copy'
-
-var log = new Logger('services/p2b-server');
-var server;
-
-// State of p2b service
-export var state = {
- init() {
- this.published = false;
- this.publishing = false;
- this.stopping = false;
- this.fullServiceName = null;
- this.date = null;
- this.numPipes = 0;
- this.numBytes = 0;
- },
- reset() {
- state.init();
- }
-};
-state.init();
-
-/*
- * Publishes the p2b service under google/p2b/{name}
- * e.g. If name is "john-tablet", p2b service will be accessible under name:
- * 'google/p2b/john-tablet'
- *
- * pipe() method can be invoked on any 'google/p2b/{name}/suffix' name where
- * suffix identifies the viewer that can format and display the stream data
- * e.g. 'google/p2b/john-tablet/console'.pipe() will display the incoming
- * data in a data table. See /app/viewer/ for a list of available viewers.
- * @param {string} name Name to publish the service under
- * @param {function} pipeRequestHandler A function that will be called when
- * a request to handle a pipe stream comes in.
- * @return {Promise} Promise that will resolve or reject when publish completes
- */
-export function publish(name, pipeRequestHandler) {
- log.debug('publishing under name:', name);
- var veyron = new Veyron(config.veyron);
- server = veyron.newServer();
- /*
- * Veyron pipe to browser service implementation.
- * Implements the p2b IDL.
- */
- var p2b = {
- pipe($suffix, $stream) {
- return new Promise(function(resolve, reject) {
- log.debug('received pipe request for:', $suffix);
- var numBytesForThisCall = 0;
-
- var bufferStream = new ByteObjectStreamAdapter();
- var streamByteCounter = new StreamByteCounter((numBytesRead) => {
- // increment total number of bytes received and total for this call
- numBytesForThisCall += numBytesRead;
- state.numBytes += numBytesRead;
- });
-
- var streamCopier = $stream.pipe(new StreamCopy());
- var stream = streamCopier.pipe(bufferStream).pipe(streamByteCounter);
- stream.copier = streamCopier;
-
- streamByteCounter.on('end', () => {
- log.debug('end of stream');
- // send total number of bytes received for this call as final result
- resolve();
- });
-
- stream.on('error', (e) => {
- log.debug('stream error', e);
- // TODO(aghassemi) envyor issue #50
- // we want to reject but because of #50 we can't
- // reject('Browser P2B threw an exception. Please see browser console for details.');
- // reject(e);
- resolve();
- });
-
- state.numPipes++;
- try {
- pipeRequestHandler($suffix, stream);
- } catch(e) {
- // TODO(aghassemi) envyor issue #50
- // we want to reject but because of #50 we can't
- // reject('Browser P2B threw an exception. Please see browser console for details.');
- log.debug('pipeRequestHandler error', e);
- resolve();
- }
-
- });
- }
- };
-
- state.publishing = true;
-
- return server.serve(config.publishNamePrefix + '/' + name, p2b).then((endpoint) => {
- log.debug('published with endpoint:', endpoint);
-
- state.published = true;
- state.publishing = false;
- state.fullServiceName = config.publishNamePrefix + '/' + name;
- state.date = new Date();
-
- return endpoint;
- }).catch((err) => { state.reset(); throw err; });
-}
-
-/*
- * Stops the service and unpublishes it, effectively destroying the service.
- * @return {Promise} Promise that will resolve or reject when stopping completes
- */
-export function stopPublishing() {
- log.debug('stopping service');
- state.stopping = true;
- return server.stop().then(function() {
- log.debug('service stopped');
- state.reset();
- return;
- });
-}
diff --git a/examples/pipetobrowser/browser/shame.js b/examples/pipetobrowser/browser/shame.js
deleted file mode 100644
index 10cb74f..0000000
--- a/examples/pipetobrowser/browser/shame.js
+++ /dev/null
@@ -1,5 +0,0 @@
-//TODO(aghassemi) Ugly random identity hack until we have proper identity
-var id= '_4EEGgFCAP-DNBoBQwEudmV5cm9uL3J1bnRpbWVzL2dvb2dsZS9zZWN1cml0eS5jaGFpblByaXZhdGVJRAD_hUIYAQIBRAEIUHVibGljSUQAAQQBBlNlY3JldAABJHZleXJvbjIvc2VjdXJpdHkvd2lyZS5DaGFpblByaXZhdGVJRAD_hzoYAQEBRQEMQ2VydGlmaWNhdGVzAAEjdmV5cm9uMi9zZWN1cml0eS93aXJlLkNoYWluUHVibGljSUQA_4kEEgFGAP-LWBgBBAEDAQROYW1lAAFHAQlQdWJsaWNLZXkAAUgBB0NhdmVhdHMAAUkBCVNpZ25hdHVyZQABIXZleXJvbjIvc2VjdXJpdHkvd2lyZS5DZXJ0aWZpY2F0ZQD_jTYYAQIBSgEFQ3VydmUAAQQBAlhZAAEfdmV5cm9uMi9zZWN1cml0eS93aXJlLlB1YmxpY0tleQD_kyQQATIBHnZleXJvbjIvc2VjdXJpdHkvd2lyZS5LZXlDdXJ2ZQD_jwQSAUsA_5U4GAECAUwBB1NlcnZpY2UAAQQBBUJ5dGVzAAEcdmV5cm9uMi9zZWN1cml0eS93aXJlLkNhdmVhdAD_lycQAQMBIXZleXJvbjIvc2VjdXJpdHkuUHJpbmNpcGFsUGF0dGVybgD_kTEYAQIBBAEBUgABBAEBUwABH3ZleXJvbjIvc2VjdXJpdHkvd2lyZS5TaWduYXR1cmUA_4L-Ae4BAwEBAgETdmV5cm9uX3AyYl9pZGVudGl0eQECQQSX1W2szGUlXbia28KqD7tzpVIHappQOKvixbijDauOdV6YrygMAmky5vLetcPzmf2Kz4QQfjf-_XpaiH2vJ3SFAAIBIEQgGWkP4DbWtZkKobftfkqE7-hPhldI1E7WM-9NHqwEASB_4e5WDr35ffYa16HkDm2pxoICFc2HemwTXgl-n5u1iQAAAQpyYW5kb206NTQwAQJBBPDpM7apzfyfgANbP3HKIo_vCTc2Jq4KbmHE8_OGjF7hkS5Do4nh6_Q-SBB1nnqSkpslgBU1kGXUCeh0P0Jza3kAAQEBASoB_4P_gQQaAUIA_4NAGAECAUMBCUlzc3VlVGltZQABQwEKRXhwaXJ5VGltZQABHXZleXJvbi9zZWN1cml0eS9jYXZlYXQuRXhwaXJ5AP-FDxABBAEJdGltZS5UaW1lAP-CJAEBDwEAAAAOy1ic8jYxcFX-XAEPAQAAAA7LWKsCNjFwVf5cAAABASBOr9ic8ql0ZSmb3HA1Z3yEJHmt62SqXHjrDT99E8buFwEgFjrqh7PJdSs8hQxl3eKyYhGfvCcULfzX0mrWBp-k_v0AAAABIML_mzA_ofWsFLMlvFukoE6vkZBJh3b7rOIxFK0HENPcAA==';
-Veyron.prototype._getIdentityPromise = function() {
- return Promise.resolve(id);
-};
diff --git a/examples/pipetobrowser/browser/views/common/common.css b/examples/pipetobrowser/browser/views/common/common.css
deleted file mode 100644
index af47ae2..0000000
--- a/examples/pipetobrowser/browser/views/common/common.css
+++ /dev/null
@@ -1,31 +0,0 @@
-.hidden {
- display: none !important;
-}
-
-paper-button {
- margin: 1em;
- width: 10em;
- display: block;
- cursor: default;
-}
-
-paper-button.colored {
- background: #4285f4;
- color:#FFFFFF;
-}
-
-paper-button.colored.red {
- background: #d34336;
-}
-
-[flex] {
- display: flex;
- flex-direction: column;
- flex: 1 1 0px;
-}
-
-[page-title] {
- font-size: 1.5em;
- color: #4285f4;
- margin: 0px;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/error/broken_robot.png b/examples/pipetobrowser/browser/views/error/broken_robot.png
deleted file mode 100644
index dc0b7f1..0000000
--- a/examples/pipetobrowser/browser/views/error/broken_robot.png
+++ /dev/null
Binary files differ
diff --git a/examples/pipetobrowser/browser/views/error/component.css b/examples/pipetobrowser/browser/views/error/component.css
deleted file mode 100644
index 94237b0..0000000
--- a/examples/pipetobrowser/browser/views/error/component.css
+++ /dev/null
@@ -1,19 +0,0 @@
-:host {
- background-image: url('broken_robot.png');
- background-repeat: no-repeat;
- background-position: right 50%;
- min-height: 300px;
- width: 100%;
- max-width: 600px;
- display: block;
-}
-
-h2 {
- font-size: 1.1em;
-}
-
-h3 {
- font-size: 0.9em;
- color: rgba(0,0,0,0.54);
- margin-right: 100px;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/error/component.html b/examples/pipetobrowser/browser/views/error/component.html
deleted file mode 100644
index 8669447..0000000
--- a/examples/pipetobrowser/browser/views/error/component.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<link rel="import" href="../../third-party/polymer/polymer.html">
-
-<polymer-element name="p2b-error">
- <template>
- <link rel="stylesheet" href="component.css">
- <h2 page-title>Error</h2>
- <h3>Sorry, some of the 1s and 0s got mixed.</h3>
- <h3>{{errorMessage}}</h3>
- </template>
- <script>
- Polymer('p2b-error', {
- errorMessage: null
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/error/view.js b/examples/pipetobrowser/browser/views/error/view.js
deleted file mode 100644
index c99c1d2..0000000
--- a/examples/pipetobrowser/browser/views/error/view.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { exists } from 'libs/utils/exists'
-import { View } from 'libs/mvc/view'
-import { Logger } from 'libs/logs/logger'
-
-var log = new Logger('views/error');
-
-/*
- * View representing application error.
- * @param {Error|String} err Error to display
- * @class
- * @extends {View}
- */
-export class ErrorView extends View {
- constructor(err) {
- var el = document.createElement('p2b-error');
- super(el);
-
- this.error = err;
- }
-
- set error(err) {
- if(!exists(err)) {
- return;
- }
-
- var errorMessage = err.toString();
- log.debug(errorMessage);
- if(exists(err.stack)) {
- log.debug(err.stack);
- }
-
- this.element.errorMessage = errorMessage;
- }
-
- get error() {
- return this.element.errorMessage;
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/help/component.css b/examples/pipetobrowser/browser/views/help/component.css
deleted file mode 100644
index 1e2e557..0000000
--- a/examples/pipetobrowser/browser/views/help/component.css
+++ /dev/null
@@ -1,33 +0,0 @@
-.name {
- font-weight: bold;
- color: rgba(0, 0, 0, 0.8);
-}
-
-.mono, .code {
- font-size: 1.1em;
- font-family: monospace;
-}
-
-.code {
- background-color: #222;
- color: #fafafa;
- padding: 1em;
- white-space: normal;
- word-break: break-all;
-}
-
-h3 {
- font-size: 1.3em;
-}
-
-h4 {
- font-size: 1.2em;
- color: rgb(51, 103, 214);
- margin-bottom: 0.5em;
-}
-
-a {
- color: #5677fc;
- text-decoration: none;
- cursor: pointer;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/help/component.html b/examples/pipetobrowser/browser/views/help/component.html
deleted file mode 100644
index d3861ef..0000000
--- a/examples/pipetobrowser/browser/views/help/component.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<link rel="import" href="../../third-party/polymer/polymer.html">
-
-<polymer-element name="p2b-help">
-<template>
- <link rel="stylesheet" href="component.css">
- <link rel="stylesheet" href="../common/common.css">
- <h2 page-title>Help</h2>
- <p>Pipe To Browser allows you to pipe anything from shell console to the browser. Piped data is then displayed in a graphical and formatted way by a viewer you can specify.</p>
- <h3>Getting Started</h3>
- <template if="{{serviceState.published}}">
- <p>Looks like you have already started the service under <span class="name">{{publishedName}}</span>, great!</p>
- </template>
- <template if="{{!serviceState.published}}">
- <p>Before we start, you need to start the service under a name. Go to Home and publish this instance of P2B under a name like <span class="name">john-tablet</span> or <span class="name">jane-desktop</span>
- </p>
- </template>
- <p>Now let's use the <span class="name">console</span> viewer. It can pretty much display anything, so it's a good one to start with</p>
- <p>In your Linux or Mac console run:</p>
- <pre class="code">echo "Hello World" | p2b {{publishedName}}/console</pre>
- <p>P2B follows a basic <span class="mono">cmd | p2b google/p2b/[name]/[viewer]</span> pattern. Where <span class="mono">[name]</span> is what you publish the service under and <span class="mono">[viewer]</span> can be the name of a built-in viewer like <span class="mono">image</span> or <span class="mono">console</span> or a Url to a remote viewer that is a P2B plug-in.</p>
- <h3>Built-in Viewers</h3>
- <p>In addition to the basic <span class="name">console</span> viewer, P2B is preloaded with the following viewers</p>
-
- <h4>Image</h4>
- <p><span class="name">image</span> can display most types of images.</p>
- <pre class="code">cat grumpy-cat.jpg | p2b {{publishedName}}/image</pre>
-
- <h4>Git Status</h4>
- <p>Ever wanted to sort, search and filter result of <span class="mono">git status</span> to make sense of it all? <span class="name">git/status</span> can do that. You need to use <span class="mono">git status --short</span> though, so we can parse it.</p>
- <pre class="code">git status --short | p2b {{publishedName}}/git/status</pre>
-
- <h4>Veyron Log Viewer</h4>
- <span class="name">vlog</span> displays Veyron logs in a DataGrid and supports sorting, searching, paging, pausing and filtering based on time and log level. DataGrid is responsive and may hide columns on smaller screens but you can always see all the fields by using the more info icon.</p>
- <pre class="code">cat vlogfile.txt | p2b {{publishedName}}/vlog</pre>
- <p>If you want to pipe logs from a Veyron service directly, you need to pipe stderr or strout first using <span class="mono">2>&1</span></p>
- <pre class="code">myVeyronServerd -v=3 2>&1 | p2b {{publishedName}}/vlog</pre>
-
- <h4>Panic Console</h4>
- <span class="name">console/panic</span> renders plaintext as <span class="name">console</span> until it detects a Go panic. Go panics crash every running goroutine, leading to a spew of stderr logs. This plugin groups goroutine crash logs into show/hide blocks. The plugin stops scrolling at the first goroutine block, which caused the panic. To further assist the debugging process, lines can be highlighted by keyword using an input filter. Don't forget to pipe both stdout and stderr to this plugin!
- <pre class="code">./goProgram 2>&1 | p2b {{publishedName}}/console/panic</pre>
-
- <h4>dev/null</h4>
- <p>No system is complete without a <span class="name">dev/null</span>. Similar to *nix <span class="mono">dev/null</span>, anything piped to it will be discarded without mercy.</p>
- <pre class="code">cat /dev/urandom | p2b {{publishedName}}/dev/null</pre>
-
- <h3>Remote Viewers</h3>
- <p>In addition to built-in viewers, ad-hoc remote viewers can be hosted anywhere and used with P2B. Remote viewers are referenced by the Url of the plug-in JavaScript file</p>
- <pre class="code">echo "Hello World" | p2b {{publishedName}}/http://googledrive.com/host/0BzmT5cnKdCAKa3hzNEVCU2tnd3c/helloworld.js</pre>
- <p>Writing remote viewers is not different than writing built-in ones and basic plug-ins are pretty straight forward to write.</p>
- <p>At high level, plug-ins are expected to implement a <span class="mono">PipeViewer</span> interface which has a <span class="mono">play(stream)</span> method. A <span class="mono">view</span> (which is a wrapper for a DOM element) is expected to be returned from <span class="mono">play(stream)</span>. You can look at the hello world remote plug-in <a href="http://googledrive.com/host/0BzmT5cnKdCAKa3hzNEVCU2tnd3c/helloworld.js" target="_blank">code on Google drive</a> to get started on writing new remote plug-ins</p>
- <p>It is also possible to write the UI layer of your plug-in in HTML and CSS as a Web Component to avoid mixing logic and layout/styling in a single file.</p>
- <p>Grumpy cat meme plug-in takes that approach. You can look at the <a href="http://googledrive.com/host/0BzmT5cnKdCAKV1p6Q0pjak5Kams/meme.js" target="_blank">JavaScript</a> and <a onClick="window.open('view-source:' + 'http://googledrive.com/host/0BzmT5cnKdCAKV1p6Q0pjak5Kams/meme.html');">HTML Web Component</a> source files.</p>
- <pre class="code">echo "I take stuff from stdin, and send them to /dev/null" | p2b {{publishedName}}/http://googledrive.com/host/0BzmT5cnKdCAKV1p6Q0pjak5Kams/meme.js</pre>
-</template>
-<script>
- Polymer('p2b-help', {
- /*
- * Dynamic binding for the state of publishing p2b service.
- */
- serviceState: null,
- get publishedName() {
- if( this.serviceState && this.serviceState.published ) {
- return this.serviceState.fullServiceName
- } else {
- return 'google/p2b/[name]';
- }
- },
-
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/views/help/view.js b/examples/pipetobrowser/browser/views/help/view.js
deleted file mode 100644
index 3ca0592..0000000
--- a/examples/pipetobrowser/browser/views/help/view.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { exists } from 'libs/utils/exists'
-import { View } from 'libs/mvc/view'
-
-/*
- * View representing the help page
- * @class
- * @extends {View}
- */
-export class HelpView extends View {
- constructor(serviceState) {
- var el = document.createElement('p2b-help');
- el.serviceState = serviceState;
- super(el);
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/loading/component.css b/examples/pipetobrowser/browser/views/loading/component.css
deleted file mode 100644
index 4411080..0000000
--- a/examples/pipetobrowser/browser/views/loading/component.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.spinner {
- margin: 1em;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/loading/component.html b/examples/pipetobrowser/browser/views/loading/component.html
deleted file mode 100644
index b6db519..0000000
--- a/examples/pipetobrowser/browser/views/loading/component.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<link rel="import" href="../../third-party/polymer/polymer.html">
-
-<polymer-element name="p2b-loading">
- <template>
- <link rel="stylesheet" href="component.css">
- <img class="spinner" src="../../libs/ui-components/common/spinner.gif" alt="Loading"/>
- </template>
- <script>
- Polymer('p2b-loading', {
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/loading/view.js b/examples/pipetobrowser/browser/views/loading/view.js
deleted file mode 100644
index 9b04512..0000000
--- a/examples/pipetobrowser/browser/views/loading/view.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import { View } from 'libs/mvc/view'
-
-/*
- * View representing a loading indicator
- * @class
- * @extends {View}
- */
-export class LoadingView extends View {
- constructor() {
- var el = document.createElement('p2b-loading');
- super(el);
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/namespace-list/component.css b/examples/pipetobrowser/browser/views/namespace-list/component.css
deleted file mode 100644
index 93ea771..0000000
--- a/examples/pipetobrowser/browser/views/namespace-list/component.css
+++ /dev/null
@@ -1,19 +0,0 @@
-[selectable] .selected {
- background-color: #00e5ff;
- opacity: 0.8;
-}
-
-[selectable] core-item {
- cursor: pointer;
-}
-
-core-item {
- box-sizing: border-box;
- border-bottom: 1px solid rgba(0,0,0,0.05);
- margin: 0;
- padding: 0 1em;
-}
-
-core-item:last-child {
- border-bottom: none;
-}
diff --git a/examples/pipetobrowser/browser/views/namespace-list/component.html b/examples/pipetobrowser/browser/views/namespace-list/component.html
deleted file mode 100644
index 176c7fd..0000000
--- a/examples/pipetobrowser/browser/views/namespace-list/component.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<link rel="import" href="../../third-party/polymer/polymer.html">
-<link rel="import" href="../../third-party/core-list/core-list.html">
-<link rel="import" href="../../third-party/core-item/core-item.html">
-
-<polymer-element name="p2b-namespace-list" attributes="names selectable">
- <template>
- <link rel="stylesheet" href="component.css">
- <template if="{{_items.length > 0}}">
- <core-list selectable?="{{selectable}}" height="40" on-core-activate="{{fireSelectEvent}}" data="{{_items}}" height="20">
- <template>
- <core-item class="{{ {selected: selected} | tokenList }}" label="{{name}}"></core-item>
- </template>
- </core-list>
- </template>
- </template>
- <script>
- Polymer('p2b-namespace-list', {
- /*
- * List of names to be displayed
- * @type {Array<string>}
- */
- names: [],
-
- /*
- * Whether the names displayed are selectable
- * if selectable, 'select' event will fire with the name of the selected item
- * @type {boolean}
- */
- selectable: false,
-
- /*
- * transformed collection of names to objects
- * @private
- */
- _items: [],
- namesChanged: function() {
- // transform from [string] to [object] since core-items expects array of objects
- this._items = this.names.map( function(n) {
- return {name: n};
- });
- },
-
- /*
- * fires the select event pass the name as event argument
- * @private
- */
- fireSelectEvent: function(e) {
- if (!this.selectable) {
- return;
- }
- this.fire('select', e.detail.data.name);
- }
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/namespace-list/view.js b/examples/pipetobrowser/browser/views/namespace-list/view.js
deleted file mode 100644
index e2b0f92..0000000
--- a/examples/pipetobrowser/browser/views/namespace-list/view.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { View } from 'libs/mvc/view'
-
-/*
- * View showing a list of all p2b services from the namespace
- * @class
- * @extends {View}
- */
-export class NamespaceListView extends View {
- constructor(items) {
- var el = document.createElement('p2b-namespace-list');
- el.items = items;
- super(el);
- }
-
-/*
- * Event that fires when user selects an item from the list.
- * @event
- * @type {string} name of the item that was selected
- */
- onSelectAction(eventHandler) {
- this.element.addEventListener('select', (e) => {
- eventHandler(e.detail);
- });
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/neighborhood/component.html b/examples/pipetobrowser/browser/views/neighborhood/component.html
deleted file mode 100644
index 1b93873..0000000
--- a/examples/pipetobrowser/browser/views/neighborhood/component.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<link rel="import" href="../../third-party/polymer/polymer.html">
-<link rel="import" href="../../views/namespace-list/component.html">
-
-<polymer-element name="p2b-neighborhood">
- <template>
- <link rel="stylesheet" href="../common/common.css">
- <h2 page-title>Neighborhood</h2>
- <p>List of PipeToBrowser instances currently published</p>
- <p2b-namespace-list names="{{existingNames}}"></p2b-namespace-list>
- </template>
- <script>
- Polymer('p2b-neighborhood', {
- /*
- * List of existing names to show
- * @type {Array<string>}
- */
- existingNames: [],
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/neighborhood/view.js b/examples/pipetobrowser/browser/views/neighborhood/view.js
deleted file mode 100644
index 2106ba2..0000000
--- a/examples/pipetobrowser/browser/views/neighborhood/view.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { View } from 'libs/mvc/view'
-
-/*
- * View displaying a list of currently published PipeToBrowsers instances
- * @class
- * @extends {View}
- */
-export class NeighborhoodView extends View {
- constructor() {
- var el = document.createElement('p2b-neighborhood');
- super(el);
- }
-
- /*
- * List of existing names to show
- * @type {Array<string>}
- */
- set existingNames(val) {
- this.element.existingNames = val;
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/page/component.css b/examples/pipetobrowser/browser/views/page/component.css
deleted file mode 100644
index 793659b..0000000
--- a/examples/pipetobrowser/browser/views/page/component.css
+++ /dev/null
@@ -1,46 +0,0 @@
-
-[drawer] {
- background-color: #FAFAFA;
- box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
-}
-
-[drawer] core-toolbar {
- background-color: rgb(66, 133, 244);
- color: #FAFAFA;
-}
-
-[sidebar] {
- padding: 0.5em;
-}
-
-[sidebar] .core-selected {
- color: #00bcd4;
-}
-
-[main] {
- height: 100%;
-}
-
-[main] core-toolbar {
- background-color: rgb(51, 103, 214);
- color: #FAFAFA;
-}
-
-core-drawer-panel:not([narrow]) paper-icon-button[icon=menu] {
- display: none;
-}
-
-.sub-page {
- padding: 1.5em;
- display: none;
-}
-
-.sub-page.core-selected {
- display: block;
-}
-
-h1, h2 {
- font-size: 1em;
- margin: 0;
- font-weight: normal;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/page/component.html b/examples/pipetobrowser/browser/views/page/component.html
deleted file mode 100644
index fc507dc..0000000
--- a/examples/pipetobrowser/browser/views/page/component.html
+++ /dev/null
@@ -1,149 +0,0 @@
-<!--TODO(aghassemi) These paths needs to be relative until issue:
-https://github.com/Polymer/vulcanize/pull/36 is merged
-otherwise they won't get vulcanized -->
-<link rel="import" href="../../third-party/polymer/polymer.html">
-<link rel="import" href="../../third-party/core-drawer-panel/core-drawer-panel.html">
-<link rel="import" href="../../third-party/core-header-panel/core-header-panel.html">
-<link rel="import" href="../../third-party/core-toolbar/core-toolbar.html">
-<link rel="import" href="../../third-party/core-menu/core-menu.html">
-<link rel="import" href="../../third-party/core-item/core-item.html">
-<link rel="import" href="../../third-party/core-selector/core-selector.html">
-<link rel="import" href="../../third-party/paper-icon-button/paper-icon-button.html">
-<link rel="import" href="../../third-party/paper-toast/paper-toast.html">
-<link rel="import" href="../../third-party/core-icons/hardware-icons.html">
-<link rel="import" href="../../third-party/core-icons/social-icons.html">
-<link rel="import" href="../../views/publish/component.html"/>
-<link rel="import" href="../../views/status/component.html"/>
-<link rel="import" href="../../views/error/component.html"/>
-<link rel="import" href="../../views/help/component.html"/>
-<link rel="import" href="../../views/loading/component.html"/>
-<link rel="import" href="../../views/pipes/component.html"/>
-<link rel="import" href="../../views/redirect-pipe-dialog/component.html"/>
-<link rel="import" href="../../views/neighborhood/component.html"/>
-<link rel="import" href="../../pipe-viewers/builtin/console/component.html"/>
-<link rel="import" href="../../pipe-viewers/builtin/console/panic/component.html"/>
-<link rel="import" href="../../pipe-viewers/builtin/git/status/component.html"/>
-<link rel="import" href="../../pipe-viewers/builtin/vlog/component.html"/>
-<link rel="import" href="../../libs/ui-components/blackhole/component.html"/>
-
-<link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
-
-<polymer-element name="p2b-page">
- <template>
- <link rel="stylesheet" href="../common/common.css">
- <link rel="stylesheet" href="component.css">
- <core-drawer-panel id="drawerPanel">
- <core-header-panel drawer>
- <core-toolbar>
- <h1>Pipe To Browser</h1>
- </core-toolbar>
-
- <core-menu sidebar valueattr="key" selected="{{ selectedSubPageKey }}">
- <template repeat="{{ subPage in subPages }}">
- <core-item key="{{ subPage.key }}" icon="{{ subPage.icon }}" label="{{ subPage.name }}" on-click="{{ activateSubPage }}"></core-item>
- </template>
- </core-menu>
-
- </core-header-panel>
- <core-header-panel main>
- <core-toolbar >
- <paper-icon-button icon="menu" on-click="{{ toggleDrawer }}"></paper-icon-button>
- <h2>{{ pageTitle }}</h2>
- </core-toolbar>
-
- <core-selector id="subPagesSelector" valueattr="key" selected="{{ selectedSubPageKey }}">
- <template repeat="{{ subPage in subPages }}">
- <div class="sub-page" key="{{ subPage.key }}"></div>
- </template>
- </core-selector>
- </core-header-panel>
- </core-drawer-panel>
- <paper-toast id="toast"></paper-toast>
- </template>
- <script>
- Polymer('p2b-page', {
-
- /*
- * Title of the page
- * @type {string}
- */
- pageTitle: '',
-
- /*
- * SubPageItem represents top level sub pages that have a sidebar navigation link
- * and a content area which gets displayed when corresponding sidebar item
- * is activated by the end user.
- * @type {object}
- */
- subPages: [],
-
- /*
- * Currently selected sub page's key
- * @type {string}
- */
- selectedSubPageKey: '',
-
- /*
- * Sets the content of the sub page identified by its key and also selects the corresponding sidebar item for it
- * @param {string} key Key of the sub page
- * @param {DOMElement} el Element to become the content of the sub page
- */
- setSubPage: function(key, el) {
- // TODO(aghassemi)
- // This setTimeout is a work-around because template may not have been activated when this is called.
- // Issue brought up with Polymer team.
- var self = this;
- setTimeout(function() {
- var subPage = self.$.subPagesSelector.querySelector('div[key="' + key + '"]');
- if(!subPage) {
- return;
- }
- if(el.parentNode !== subPage) {
- subPage.innerHTML = '';
- subPage.appendChild(el);
- }
- self.selectedSubPageKey = key;
- });
- },
-
- /*
- * Displays a message toast for a few seconds e.g. "Saved Successfully"
- * @param {string} text Text of the toast
- */
- showToast: function(text) {
- this.$.toast.text = text;
- this.$.toast.show();
- },
-
- /*
- * handler for when a sidebar item is clicked
- * @param {string} key Key of the page
- * @private
- */
- activateSubPage: function(e) {
- // find the targeted subPage item
- var key = e.toElement.getAttribute('key');
- var subPage = this.subPages.filter(function(s) {
- return s.key === key;
- })[0];
-
- // call the sub page's delegate
- if(subPage.onActivate) {
- subPage.onActivate.call(subPage.onActivate);
- }
-
- // toggle the drawer
- this.toggleDrawer();
- },
-
- /*
- * toggles the drawer
- * @private
- */
- toggleDrawer: function() {
- this.$.drawerPanel.togglePanel();
- }
-
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/page/view.js b/examples/pipetobrowser/browser/views/page/view.js
deleted file mode 100644
index e946181..0000000
--- a/examples/pipetobrowser/browser/views/page/view.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import { View } from 'libs/mvc/view'
-
-/*
- * View representing the application page. Includes page level navigation, toolbar
- * and other page chrome. Used as the container for all other views.
- * @class
- * @extends {View}
- */
-export class PageView extends View {
- constructor() {
- var el = document.createElement('p2b-page');
- el.subPages = [];
- super(el);
- }
-
- /*
- * Displays the given view inside the sub page area identified by the key.
- * @param {String} subPageKey Key for the sub page to display.
- * @param {View} view View to display.
- */
- setSubPageView(subPageKey, view) {
- this.element.setSubPage(subPageKey, view.element);
- }
-
- /*
- * Displayed a message toast for a few seconds e.g. "Saved Successfully"
- * @type {SubPageItem}
- */
- showToast(text) {
- this.element.showToast(text);
- }
-
- /*
- * Collection of sub pages
- * @type {SubPageItem}
- */
- get subPages() {
- return this.element.subPages;
- }
-
- /*
- * Title of the page
- * @type {string}
- */
- set title(title) {
- this.element.pageTitle = title;
- }
-
-}
-
-/*
- * SubPageItem represents top level sub pages that have a sidebar navigation link
- * and a content area which gets displayed when corresponding sidebar item
- * is activated by the end user.
- * @param {String} key Unique identified for this sub page
- * @class
- */
-export class SubPageItem {
- constructor(key) {
- /*
- * Name of the page. Normally displayed as the sidebar navigation item text
- * @type {String}
- */
- this.name = name;
-
- /*
- * Unique identified for this sub page
- * @type {String}
- */
- this.key = key;
-
- /*
- * Function that's called when user activates the sub page, normally by clicking
- * the sidebar navigation items for the sub page
- * @type {Function}
- */
- this.onActivate = null;
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/pipes/component.css b/examples/pipetobrowser/browser/views/pipes/component.css
deleted file mode 100644
index 819c741..0000000
--- a/examples/pipetobrowser/browser/views/pipes/component.css
+++ /dev/null
@@ -1,39 +0,0 @@
-#tabs {
- background-color: #00bcd4;
- color: #fafafa;
- box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
- width: 100%;
- z-index: 1;
-}
-
-#tabs > paper-tab:not(:last-child) {
- border-right: solid 1px rgba(0, 0, 0, 0.1);
-}
-
-#tabPages {
- position: relative;
- overflow: hidden;
-}
-
-.no-pipes-bg {
- background-image: url('factory.png');
- background-size: cover;
- background-repeat: no-repeat;
- background-position: 70% 50%;
- height: 100%;
- width: 100%;
- opacity: 0.15;
-}
-
-.empty-message {
- padding: 1em;
- position: absolute;
-}
-
-.container {
- position: absolute;
- bottom: 0;
- top: 0;
- right: 0;
- left: 0;
-}
diff --git a/examples/pipetobrowser/browser/views/pipes/component.html b/examples/pipetobrowser/browser/views/pipes/component.html
deleted file mode 100644
index a2a2286..0000000
--- a/examples/pipetobrowser/browser/views/pipes/component.html
+++ /dev/null
@@ -1,180 +0,0 @@
-<link rel="import" href="../../third-party/polymer/polymer.html">
-<link rel="import" href="../../third-party/core-pages/core-pages.html">
-<link rel="import" href="../../third-party/core-icons/core-icons.html">
-<link rel="import" href="../../third-party/core-icon-button/core-icon-button.html">
-<link rel="import" href="../../third-party/core-toolbar/core-toolbar.html">
-<link rel="import" href="../../third-party/core-selector/core-selector.html">
-<link rel="import" href="../../third-party/paper-tabs/paper-tabs.html">
-<link rel="import" href="tab-content/component.html">
-<link rel="import" href="tab-toolbar/component.html">
-
-<polymer-element name="p2b-pipes">
- <template>
- <link rel="stylesheet" href="../common/common.css">
- <link rel="stylesheet" href="component.css">
- <div class="container" flex>
- <template if="{{ numTabs == 0 }}">
- <h2 page-title class="empty-message">No pipes to show...</h2>
- <div class="no-pipes-bg"></div>
- </template>
-
- <div id="tabsContainer" class="{{ {hidden : numTabs == 0} | tokenList}}" flex>
- <paper-tabs id="tabs" class="{{ {hidden : numTabs <= 1} | tokenList}}" on-core-select="{{ handleTabSelectionChange }}" valueattr="key" selected="{{ selectedTabKey }}" noink></paper-tabs>
- <core-selector id="tabPages" valueattr="key" selected="{{ selectedTabKey }}" flex></core-selector>
- </div>
- </div>
- </template>
- <script>
- Polymer('p2b-pipes', {
-
- /*
- * Map of existing pipe tabs. Key is the tab key.
- * @type {set}
- * @private
- */
- pipeTabs: {},
-
- /*
- * Key of currently selected tab
- * @type {string}
- */
- selectedTabKey : '',
-
- /*
- * Stack of previously selected tabs.
- * @type {Array<string>}
- * @private
- */
- selectionHistoryStack: [],
-
- ready: function() {
- this.numTabs = 0
- },
-
- /*
- * Adds a new tab
- * @param {string} key Key of the tab to add
- * @param {string} name Name of the tab to add
- * @param {DOMElement} el Content of the tab
- * @param {function} onClose Optional onClose callback.
- */
- addTab: function(key, name, el, onClose) {
- var self = this;
-
- // Create a tab thumb
- var tab = document.createElement('paper-tab');
- tab.key = key;
- tab.textContent = name;
-
- // Create a tab toolbar and assign the close handler
- var tabToolbar = document.createElement('p2b-pipes-tab-toolbar');
- tabToolbar.toolbarTitle = name;
- tabToolbar.addEventListener('close-action', function() {
- self.removeTab(key);
- if (onClose) {
- onClose();
- }
- });
- tabToolbar.addEventListener('fullscreen-action', function() {
- var tabContent = self.pipeTabs[key].tabContent;
- tabContent.fullscreen();
- });
-
- // Create the content of the tab
- var tabContent = document.createElement('p2b-pipes-tab-content');
- tabContent.setAttribute('key', key);
- tabContent.appendChild(tabToolbar);
- tabContent.appendChild(el);
-
- this.$.tabPages.appendChild(tabContent);
-
- // Add the tab to our list.
- this.pipeTabs[key] = {
- name: name,
- tab: tab,
- tabContent: tabContent,
- tabToolbar: tabToolbar
- };
-
- this.numTabs++;
-
- this.selectedTabKey = key;
- requestAnimationFrame(function() {
- self.$.tabs.appendChild(tab);
- });
- },
-
- /*
- * Adds a new toolbar action for the tab's toolbar
- * @param {string} tabKey Key of the tab to add action to
- * @param icon {string} icon Icon name for the action
- * @param onClick {function} event handler for the action
- */
- addToolbarAction: function(tabKey, icon, onClick) {
- if (!this.pipeTabs[tabKey]) {
- return;
- }
- var toolbar = this.pipeTabs[tabKey].tabToolbar;
- toolbar.add(icon, onClick);
- },
-
- /*
- * Removes a tab
- * @param {string} key Key of the tab to remove
- */
- removeTab: function(key) {
- if (!this.pipeTabs[key]) {
- return;
- }
- // Remove tab thumb and content
- var tab = this.pipeTabs[key].tab;
- tab.remove();
- var tabContent = this.pipeTabs[key].tabContent;
- tabContent.remove();
-
- // Delete tab from the map
- delete this.pipeTabs[key];
- this.numTabs--;
-
- // Select an existing tab from previous selection history
- var toSelect = this.selectionHistoryStack.pop();
- while ( toSelect && !this.pipeTabs[toSelect] ) {
- // pop until we find one that still exists
- toSelect = this.selectionHistoryStack.pop();
- }
- if (toSelect) {
- this.selectedTabKey = toSelect;
- }
- },
-
- /*
- * Replaces content of a tab
- * @param {string} key Key of the tab to replace content for
- * @param {string} newName new name for the tab
- * @param {DOMElement} el New content of the tab
- */
- replaceTabContent: function(key, newName, newEl) {
- if (!this.pipeTabs[key]) {
- return;
- }
- var tabContent = this.pipeTabs[key].tabContent;
- tabContent.replaceTabContent(newEl);
- if (newName) {
- this.pipeTabs[key].tab.textContent = newName;
- this.pipeTabs[key].tabToolbar.toolbarTitle = newName;
- }
- },
-
- /*
- * Adds the tab selection to history when selection changes
- * @private
- */
- handleTabSelectionChange: function(e) {
- if (!e.detail.isSelected){
- return;
- }
- this.selectionHistoryStack.push(this.selectedTabKey);
- }
- });
- </script>
-</polymer-element>
diff --git a/examples/pipetobrowser/browser/views/pipes/factory.png b/examples/pipetobrowser/browser/views/pipes/factory.png
deleted file mode 100644
index 6745634..0000000
--- a/examples/pipetobrowser/browser/views/pipes/factory.png
+++ /dev/null
Binary files differ
diff --git a/examples/pipetobrowser/browser/views/pipes/tab-content/component.css b/examples/pipetobrowser/browser/views/pipes/tab-content/component.css
deleted file mode 100644
index d3eea80..0000000
--- a/examples/pipetobrowser/browser/views/pipes/tab-content/component.css
+++ /dev/null
@@ -1,25 +0,0 @@
-/* become offset parent for content container */
-.tab-main {
- position: relative;
-}
-
-/* content fills remaining space */
-.tab-main-content {
- overflow: auto;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
-}
-
-/* hidden, unless selected */
-:host(.core-selected) {
- display: flex !important;
-}
-
-:host {
- display: none !important;
-}
-
-
diff --git a/examples/pipetobrowser/browser/views/pipes/tab-content/component.html b/examples/pipetobrowser/browser/views/pipes/tab-content/component.html
deleted file mode 100644
index 0f18ddd..0000000
--- a/examples/pipetobrowser/browser/views/pipes/tab-content/component.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<link rel="import" href="../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../third-party/core-toolbar/core-toolbar.html">
-
-<polymer-element name="p2b-pipes-tab-content" flex>
- <template>
- <link rel="stylesheet" href="component.css">
- <content select="p2b-pipes-tab-toolbar"></content>
- <div class="tab-main" flex>
- <div id="main" class="tab-main-content" flex>
- <content></content>
- </div>
- </div>
- </template>
- <script>
- Polymer('p2b-pipes-tab-content', {
-
- /*
- * Replaces existing content of the tab with the new element
- * @param {DOMElement} new element to replace existing content
- */
- replaceTabContent: function(newEl) {
- //TODO(aghassemi) There must be a better way for these .innerHTML='', figure it out.
- this.$.main.innerHTML = '';
- this.$.main.appendChild(newEl);
- },
-
- /*
- * Puts the tab content into fullscreen mode
- */
- fullscreen: function() {
- var flag = Element.ALLOW_KEYBOARD_INPUT;
- if (this.$.main.requestFullscreen) {
- this.$.main.requestFullscreen(flag);
- } else if( this.$.main.webkitRequestFullscreen ) {
- this.$.main.webkitRequestFullscreen(flag);
- }
- }
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/pipes/tab-toolbar/component.css b/examples/pipetobrowser/browser/views/pipes/tab-toolbar/component.css
deleted file mode 100644
index acb7187..0000000
--- a/examples/pipetobrowser/browser/views/pipes/tab-toolbar/component.css
+++ /dev/null
@@ -1,11 +0,0 @@
-core-toolbar {
- background-color: rgba(0, 0, 0, 0.10);
- box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
- z-index: 1;
- font-size: 1em;
- height: 48px;
-}
-
-core-toolbar::shadow .toolbar-tools {
- height: 48px;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/pipes/tab-toolbar/component.html b/examples/pipetobrowser/browser/views/pipes/tab-toolbar/component.html
deleted file mode 100644
index 3514b67..0000000
--- a/examples/pipetobrowser/browser/views/pipes/tab-toolbar/component.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<link rel="import" href="../../../third-party/polymer/polymer.html">
-<link rel="import" href="../../../third-party/paper-icon-button/paper-icon-button.html">
-
-<polymer-element name="p2b-pipes-tab-toolbar">
- <template>
- <link rel="stylesheet" href="component.css">
- <core-toolbar>
- <span flex>
- {{ toolbarTitle }}
- </span>
- <span id="customActions"></span>
- <paper-icon-button id="fullscreenIcon" icon="fullscreen" on-click="{{ fireFullscreenAction }}"></paper-icon-button>
- <paper-icon-button icon="close" on-click="{{ fireCloseAction }}"></paper-icon-button>
- </core-toolbar>
- </template>
- <script>
- Polymer('p2b-pipes-tab-toolbar', {
-
- /*
- * Title of the toolbar
- * @type {string}
- */
- toolbarTitle: '',
-
- /*
- * Event that's fired when close action of the toolbar is triggered
- * @event
- */
- fireCloseAction: function() {
- this.fire('close-action');
- },
-
- /*
- * Event that's fired when fullscreen action of the toolbar is triggered
- * @event
- */
- fireFullscreenAction: function() {
- this.fire('fullscreen-action');
- },
-
- /*
- * Adds a new action to the toolbar
- * @param icon {string} icon Icon for the action
- * @param onClick {function} event handler for the action
- */
- add: function(icon, onClick) {
- var button = document.createElement('paper-icon-button');
- button.icon = icon;
- button.addEventListener('click', onClick);
- this.$.customActions.appendChild(button);
- }
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/pipes/view.js b/examples/pipetobrowser/browser/views/pipes/view.js
deleted file mode 100644
index 78fcd20..0000000
--- a/examples/pipetobrowser/browser/views/pipes/view.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import { View } from 'libs/mvc/view'
-
-/*
- * View representing a collection of pipes displayed in tabs.
- * this view manages the tabs and the empty message when no pipes available
- * @class
- * @extends {View}
- */
-export class PipesView extends View {
- constructor() {
- var el = document.createElement('p2b-pipes');
- super(el);
- }
-
- /*
- * Adds the given view as a new pipe viewer tab
- * @param {string} key A string key identifier for the tab.
- * @param {string} name A short name for the tab that will be displayed as
- * the tab title
- * @param {View} view View to show inside the tab.
- * @param {function} onClose Optional onClose callback.
- */
- addTab(key, name, view, onClose) {
- this.element.addTab(key, name, view.element, onClose);
- }
-
- /*
- * Adds a new toolbar action for the tab's toolbar
- * @param {string} key Key of the tab to add action to
- * @param icon {string} icon key for the action
- * @param onClick {function} event handler for the action
- */
- addToolbarAction(tabKey, icon, onClick) {
- this.element.addToolbarAction(tabKey, icon, onClick);
- }
-
- /*
- * Replaces the content of the tab identified via key by the new view.
- * @param {string} key A string key identifier for the tab.
- * @param {string} newName New name for the tab
- * @param {View} view View to replace the current tab content
- */
- replaceTabView(key, newName, newView) {
- this.element.replaceTabContent(key, newName, newView.element);
- }
-}
diff --git a/examples/pipetobrowser/browser/views/publish/component.css b/examples/pipetobrowser/browser/views/publish/component.css
deleted file mode 100644
index 7f072c0..0000000
--- a/examples/pipetobrowser/browser/views/publish/component.css
+++ /dev/null
@@ -1,4 +0,0 @@
-paper-input {
- width: 100%;
- max-width: 30em;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/publish/component.html b/examples/pipetobrowser/browser/views/publish/component.html
deleted file mode 100644
index 9396a11..0000000
--- a/examples/pipetobrowser/browser/views/publish/component.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<link rel="import" href="../../third-party/polymer/polymer.html">
-<link rel="import" href="../../third-party/paper-input/paper-input.html">
-<link rel="import" href="../../third-party/paper-button/paper-button.html">
-
-<polymer-element name="p2b-publish" attributes="publishState">
-
- <template id="template">
- <link rel="stylesheet" href="../common/common.css">
- <link rel="stylesheet" href="component.css">
- <paper-input id="publishNameInput" label="Name to publish under (e.g. john-tablet)" error="You must pick a name!" floatinglabel/></paper-input>
- <paper-button class="paper colored" inkColor="#3367d6" on-click="{{ publishAction }}">Publish</paper-button>
- </template>
- <script>
- Polymer('p2b-publish', {
-
- /*
- * Publish action. Fires when user decided to publish the p2b service.
- * user-entered name of the service will be provided as value of the event
- * @event
- */
- publishAction: function() {
- var name = this.$.publishNameInput.value.trim();
- if(name === "") {
- this.$.publishNameInput.invalid = true;
- this.$.publishNameInput.classList.toggle('invalid', true);
- return;
- }
- this.fire('publish', { publishName: name });
- }
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/publish/view.js b/examples/pipetobrowser/browser/views/publish/view.js
deleted file mode 100644
index 66b386d..0000000
--- a/examples/pipetobrowser/browser/views/publish/view.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { View } from 'libs/mvc/view'
-
-/*
- * View representing the state and interaction for publishing the p2b service.
- * @class
- * @extends {View}
- */
-export class PublishView extends View {
- constructor(publishState) {
- var el = document.createElement('p2b-publish');
- el.publishState = publishState;
- super(el);
- }
-
-/*
- * Event representing user's intention to publish the p2b service under the provided name
- * @event
- * @type {string} Requested name for service to be published under
- */
- onPublishAction(eventHandler) {
- this.element.addEventListener('publish', (e) => {
- eventHandler(e.detail.publishName);
- });
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/redirect-pipe-dialog/component.css b/examples/pipetobrowser/browser/views/redirect-pipe-dialog/component.css
deleted file mode 100644
index b1bdca0..0000000
--- a/examples/pipetobrowser/browser/views/redirect-pipe-dialog/component.css
+++ /dev/null
@@ -1,22 +0,0 @@
-paper-input {
- width: 90%;
-}
-
-paper-input, paper-checkbox {
- display: block;
-}
-
-paper-dialog {
- max-width: 40em;
- width: 80vw;
-}
-
-paper-button[affirmative] {
- color: #4285f4;
-}
-
-.label {
- margin: 0;
- margin-top: 1em;
- font-size: 1.1em;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/redirect-pipe-dialog/component.html b/examples/pipetobrowser/browser/views/redirect-pipe-dialog/component.html
deleted file mode 100644
index 9ede48c..0000000
--- a/examples/pipetobrowser/browser/views/redirect-pipe-dialog/component.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<link rel="import" href="../../third-party/polymer/polymer.html">
-<link rel="import" href="../../third-party/paper-input/paper-input.html">
-<link rel="import" href="../../third-party/paper-button/paper-button.html">
-<link rel="import" href="../../third-party/paper-dialog/paper-dialog.html">
-<link rel="import" href="../../third-party/paper-dialog/paper-dialog-transition.html">
-<link rel="import" href="../../views/namespace-list/component.html">
-
-<polymer-element name="p2b-redirect-pipe-dialog">
-
- <template id="template">
- <link rel="stylesheet" href="../common/common.css">
- <link rel="stylesheet" href="component.css">
- <paper-dialog id="dialog" heading="Redirect" transition="paper-dialog-transition-bottom">
- <p>
- <paper-input focused id="nameInput" label="Name to redirect to" floatinglabel></paper-input>
- <paper-checkbox id="newDataOnly" label="Only redirect new data"></paper-checkbox>
- <template if="{{existingNames.length > 0}}">
- <h2 class="label">Currently online</h2>
- <p2b-namespace-list selectable on-select="{{updateNameInput}}" names="{{existingNames}}"></p2b-namespace-list>
- </template>
- </p>
- <paper-button label="Cancel" dismissive></paper-button>
- <paper-button label="Redirect" affirmative default on-tap="{{ fireRedirectActionEvent }}"></paper-button>
- </paper-dialog>
- </template>
- <script>
- Polymer('p2b-redirect-pipe-dialog', {
-
- /*
- * List of existing names to show in the dialog for the user to pick from
- * @type {Array<string>}
- */
- existingNames: [],
-
- ready: function() {
- var self = this;
- var dialog = this.$.dialog;
- var container = document.querySelector('#redirectDialogContainer');
- if (!container) {
- var container = document.createElement('div');
- container.id = 'redirectDialogContainer';
- document.body.appendChild(container);
- }
- this.container = container;
- },
-
- /*
- * Opens the dialog
- */
- open: function() {
- this.container.innerHTML = ''
- this.container.appendChild(this);
- this.$.dialog.toggle();
- },
-
- /*
- * Fires redirect event representing user's intention to redirect
- * @type {string} Requested name for service to be redirected
- * @type {boolean} Whether only new data should be redirected
- */
- fireRedirectActionEvent: function() {
- var name = this.$.nameInput.value;
- this.fire('redirect', {
- name: name,
- newDataOnly: this.$.newDataOnly.checked
- });
- },
-
- /*
- * Updates the input value
- * @private
- */
- updateNameInput: function(e) {
- this.$.nameInput.value = e.detail;
- }
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/redirect-pipe-dialog/view.js b/examples/pipetobrowser/browser/views/redirect-pipe-dialog/view.js
deleted file mode 100644
index d369c49..0000000
--- a/examples/pipetobrowser/browser/views/redirect-pipe-dialog/view.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import { View } from 'libs/mvc/view'
-
-/*
- * View representing a dialog that asks the user where they want to redirect
- * the current pipe and whether only new data should be redirected
- * @class
- * @extends {View}
- */
-export class RedirectPipeDialogView extends View {
- constructor() {
- var el = document.createElement('p2b-redirect-pipe-dialog');
- super(el);
- }
-
- /*
- * Opens the Redirect Pipe Dialog
- */
- open() {
- this.element.open();
- }
-
- /*
- * List of existing names to show in the dialog for the user to pick from
- * @type {Array<string>}
- */
- set existingNames(val) {
- this.element.existingNames = val;
- }
-
- /*
- * Event representing user's intention to redirect
- * @event
- * @type {string} Requested name for service to be redirected
- * @type {boolean} Whether only new data should be redirected
- */
- onRedirectAction(eventHandler) {
- this.element.addEventListener('redirect', (e) => {
- eventHandler(e.detail.name, e.detail.newDataOnly);
- });
- }
-
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/status/component.css b/examples/pipetobrowser/browser/views/status/component.css
deleted file mode 100644
index 2eca7d3..0000000
--- a/examples/pipetobrowser/browser/views/status/component.css
+++ /dev/null
@@ -1,14 +0,0 @@
-h3 {
- font-size: 1.0em;
- padding-bottom: 0.2em;
- color: #4285f4;
- border-bottom: 1px solid rgba(0,0,0,0.05);
- font-weight: normal;
- text-transform: uppercase;
- margin: 0;
-}
-
-p {
- margin-top: 0.2em;
- margin-bottom: 1.5em;
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/status/component.html b/examples/pipetobrowser/browser/views/status/component.html
deleted file mode 100644
index 14143c1..0000000
--- a/examples/pipetobrowser/browser/views/status/component.html
+++ /dev/null
@@ -1,102 +0,0 @@
-<link rel="import" href="../../third-party/polymer/polymer.html">
-<link rel="import" href="../../third-party/paper-button/paper-button.html">
-
-<polymer-element name="p2b-status" attributes="status">
-
- <template>
- <link rel="stylesheet" href="../common/common.css">
- <link rel="stylesheet" href="component.css">
- <h3>Status</h3>
- <p>{{ serviceState | formatServiceState }}</p>
- <div class="{{ {hidden : !serviceState.published} | tokenList }}">
- <h3>Name</h3>
- <p>{{ serviceState.fullServiceName }}</p>
-
- <h3>Published on</h3>
- <p>{{ serviceState.date | formatDate }}</p>
-
- <h3>Running Since</h3>
- <p>{{ runningSince }}</p>
-
- <h3>Number of pipe requests</h3>
- <p>{{ serviceState.numPipes | formatInteger }}</p>
-
- <h3>Total bytes received</h3>
- <p>{{ serviceState.numBytes | formatBytes }}</p>
- </div>
- <paper-button class="paper colored red" inkColor="#A9352C" on-click="{{ stopAction }}">Stop</paper-button>
- </template>
- <script>
- System.import('libs/utils/formatting').then(function(formatter) {
- Polymer('p2b-status', {
-
- ready: function() {
- this.runningSince = 'just now';
- },
-
- attached: function() {
- // Update the running since every second.
- this.runningSinceIntervalId = setInterval(this.updateRunningSince.bind(this), 1000);
- },
-
- detached: function() {
- clearInterval(this.runningSinceIntervalId);
- },
-
- /*
- * Dynamic binding for the state of publishing p2b service.
- * Any changes to this object will be reflected in the UI automatically
- */
- serviceState: null,
-
- /*
- * Human friendly formatting functions. Because polymer filter expressions
- * don't accept obj.func we wrap them here
- * @private
- */
- formatDate: formatter.formatDate,
- formatInteger: formatter.formatInteger,
- formatBytes: formatter.formatBytes,
-
- /*
- * Auto-updating Uptime text
- * @private
- * @type {string}
- */
- updateRunningSince: function() {
- if (!this.serviceState) { return; }
- this.runningSince = formatter.formatRelativeTime(this.serviceState.date);
- },
-
- /*
- * Status text
- * @private
- * @type {string}
- */
- formatServiceState: function(serviceState) {
- if (!serviceState) {
- return '';
- }
- if (serviceState.published) {
- return 'Published';
- } else if(serviceState.publishing) {
- return 'Publishing';
- } else if(serviceState.stopping) {
- return 'Stopping';
- } else {
- return 'Stopped';
- }
- },
-
- /*
- * Stop action. Fires when user decides to stop the p2b service.
- * @event
- */
- stopAction: function() {
- this.fire('stop');
- }
-
- });
- });
- </script>
-</polymer-element>
\ No newline at end of file
diff --git a/examples/pipetobrowser/browser/views/status/view.js b/examples/pipetobrowser/browser/views/status/view.js
deleted file mode 100644
index 8792b8c..0000000
--- a/examples/pipetobrowser/browser/views/status/view.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import { View } from 'libs/mvc/view'
-
-/*
- * View representing the state and interaction for publishing the p2b service.
- * @class
- * @extends {View}
- */
-export class StatusView extends View {
- constructor(serviceState) {
- var el = document.createElement('p2b-status');
- el.serviceState = serviceState;
- super(el);
- }
-
-/*
- * Event representing user's intention to stop the published service
- * @event
- */
- onStopAction(eventHandler) {
- this.element.addEventListener('stop', () => {
- eventHandler();
- });
- }
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/p2b.vdl b/examples/pipetobrowser/p2b.vdl
deleted file mode 100644
index 3a20904..0000000
--- a/examples/pipetobrowser/p2b.vdl
+++ /dev/null
@@ -1,7 +0,0 @@
-package pipetobrowser
-
-// Viewer allows clients to stream data to it and to request a particular viewer to format and display the data.
-type Viewer interface {
- // Pipe creates a bidirectional pipe between client and viewer service, returns total number of bytes received by the service after streaming ends
- Pipe() stream<[]byte, _> (any, error)
-}
\ No newline at end of file
diff --git a/examples/pipetobrowser/p2b.vdl.go b/examples/pipetobrowser/p2b.vdl.go
deleted file mode 100644
index 479fd6c..0000000
--- a/examples/pipetobrowser/p2b.vdl.go
+++ /dev/null
@@ -1,337 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: p2b.vdl
-
-package pipetobrowser
-
-import (
- // The non-user imports are prefixed with "_gen_" to prevent collisions.
- _gen_io "io"
- _gen_veyron2 "veyron2"
- _gen_context "veyron2/context"
- _gen_ipc "veyron2/ipc"
- _gen_naming "veyron2/naming"
- _gen_vdlutil "veyron2/vdl/vdlutil"
- _gen_wiretype "veyron2/wiretype"
-)
-
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
-const _ = _gen_wiretype.TypeIDInvalid
-
-// Viewer allows clients to stream data to it and to request a particular viewer to format and display the data.
-// Viewer is the interface the client binds and uses.
-// Viewer_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type Viewer_ExcludingUniversal interface {
- // Pipe creates a bidirectional pipe between client and viewer service, returns total number of bytes received by the service after streaming ends
- Pipe(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply ViewerPipeCall, err error)
-}
-type Viewer interface {
- _gen_ipc.UniversalServiceMethods
- Viewer_ExcludingUniversal
-}
-
-// ViewerService is the interface the server implements.
-type ViewerService interface {
-
- // Pipe creates a bidirectional pipe between client and viewer service, returns total number of bytes received by the service after streaming ends
- Pipe(context _gen_ipc.ServerContext, stream ViewerServicePipeStream) (reply _gen_vdlutil.Any, err error)
-}
-
-// ViewerPipeCall is the interface for call object of the method
-// Pipe in the service interface Viewer.
-type ViewerPipeCall interface {
-
- // SendStream returns the send portion of the stream
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no
- // buffer space available. Calls to Send after having called Close
- // or Cancel will fail. Any blocked Send calls will be unblocked upon
- // calling Cancel.
- Send(item []byte) error
-
- // Close indicates to the server that no more items will be sent;
- // server Recv calls will receive io.EOF after all sent items. This is
- // an optional call - it's used by streaming clients that need the
- // server to receive the io.EOF terminator before the client calls
- // Finish (for example, if the client needs to continue receiving items
- // from the server after having finished sending).
- // Calls to Close after having called Cancel will fail.
- // Like Send, Close blocks when there's no buffer space available.
- Close() error
- }
-
- // Finish performs the equivalent of SendStream().Close, then blocks until the server
- // is done, and returns the positional return values for call.
- // If Cancel has been called, Finish will return immediately; the output of
- // Finish could either be an error signalling cancelation, or the correct
- // positional return values from the server depending on the timing of the
- // call.
- //
- // Calling Finish is mandatory for releasing stream resources, unless Cancel
- // has been called or any of the other methods return an error.
- // Finish should be called at most once.
- Finish() (reply _gen_vdlutil.Any, err error)
-
- // Cancel cancels the RPC, notifying the server to stop processing. It
- // is safe to call Cancel concurrently with any of the other stream methods.
- // Calling Cancel after Finish has returned is a no-op.
- Cancel()
-}
-
-type implViewerPipeStreamSender struct {
- clientCall _gen_ipc.Call
-}
-
-func (c *implViewerPipeStreamSender) Send(item []byte) error {
- return c.clientCall.Send(item)
-}
-
-func (c *implViewerPipeStreamSender) Close() error {
- return c.clientCall.CloseSend()
-}
-
-// Implementation of the ViewerPipeCall interface that is not exported.
-type implViewerPipeCall struct {
- clientCall _gen_ipc.Call
- writeStream implViewerPipeStreamSender
-}
-
-func (c *implViewerPipeCall) SendStream() interface {
- Send(item []byte) error
- Close() error
-} {
- return &c.writeStream
-}
-
-func (c *implViewerPipeCall) Finish() (reply _gen_vdlutil.Any, err error) {
- if ierr := c.clientCall.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (c *implViewerPipeCall) Cancel() {
- c.clientCall.Cancel()
-}
-
-type implViewerServicePipeStreamIterator struct {
- serverCall _gen_ipc.ServerCall
- val []byte
- err error
-}
-
-func (s *implViewerServicePipeStreamIterator) Advance() bool {
- s.err = s.serverCall.Recv(&s.val)
- return s.err == nil
-}
-
-func (s *implViewerServicePipeStreamIterator) Value() []byte {
- return s.val
-}
-
-func (s *implViewerServicePipeStreamIterator) Err() error {
- if s.err == _gen_io.EOF {
- return nil
- }
- return s.err
-}
-
-// ViewerServicePipeStream is the interface for streaming responses of the method
-// Pipe in the service interface Viewer.
-type ViewerServicePipeStream interface {
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() []byte
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-}
-
-// Implementation of the ViewerServicePipeStream interface that is not exported.
-type implViewerServicePipeStream struct {
- reader implViewerServicePipeStreamIterator
-}
-
-func (s *implViewerServicePipeStream) RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. The client must call Cancel if it does
- // not iterate through all elements (i.e. until Advance
- // returns false). Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() []byte
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
-} {
- return &s.reader
-}
-
-// BindViewer returns the client stub implementing the Viewer
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindViewer(name string, opts ..._gen_ipc.BindOpt) (Viewer, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubViewer{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerViewer creates a new server stub.
-//
-// It takes a regular server implementing the ViewerService
-// interface, and returns a new server stub.
-func NewServerViewer(server ViewerService) interface{} {
- return &ServerStubViewer{
- service: server,
- }
-}
-
-// clientStubViewer implements Viewer.
-type clientStubViewer struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubViewer) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubViewer) Pipe(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply ViewerPipeCall, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Pipe", nil, opts...); err != nil {
- return
- }
- reply = &implViewerPipeCall{clientCall: call, writeStream: implViewerPipeStreamSender{clientCall: call}}
- return
-}
-
-func (__gen_c *clientStubViewer) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubViewer) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubViewer) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubViewer wraps a server that implements
-// ViewerService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubViewer struct {
- service ViewerService
-}
-
-func (__gen_s *ServerStubViewer) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Pipe":
- return []interface{}{}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubViewer) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Pipe"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- {Name: "", Type: 66},
- },
- InStream: 68,
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "anydata", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x43, Name: "", Tags: []string(nil)}}
-
- return result, nil
-}
-
-func (__gen_s *ServerStubViewer) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubViewer) Pipe(call _gen_ipc.ServerCall) (reply _gen_vdlutil.Any, err error) {
- stream := &implViewerServicePipeStream{reader: implViewerServicePipeStreamIterator{serverCall: call}}
- reply, err = __gen_s.service.Pipe(call, stream)
- return
-}
diff --git a/examples/pipetobrowser/p2b/main.go b/examples/pipetobrowser/p2b/main.go
deleted file mode 100644
index 03d44ea..0000000
--- a/examples/pipetobrowser/p2b/main.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Pipe To Browser client.
-// This executable pipes its sdtin to p2b service running in the browser
-package main
-
-import (
- "flag"
- "fmt"
- "io"
- "os"
-
- "veyron2"
- "veyron2/rt"
-
- "veyron/examples/pipetobrowser"
-)
-
-const usage = `
-%s is a Pipe To Browser client. It allows one to pipe any stdout stream from console to the browser.
-Data being piped to the browser then is displayed in a graphical and formatted way by a "viewer".
-
-Usage:
-
- %s [<name>/<viewer>]
-
- For example:
-
- ls -l | p2b google/p2b/jane/console
-
- or
-
- cat cat.jpg | google/p2b/jane/image
-
- where <name> (google/p2b/jane) is the object name where p2b
- service is running in the browser. <viewer> (console, image) specifies what
- viewer should be used to display the data.
-
- To redirect stderr of a process, in *nix system you can use 2>&1 before piping to P2B.
-
- For example many daemons may write log lines to stderr instead of stdout:
-
- serverd -alsologtostderr=true 2>&1 | google/p2b/jane/vlog
-`
-
-func Usage() {
- fmt.Fprintf(os.Stdout, usage, os.Args[0], os.Args[0])
-}
-
-type sender interface {
- Send(p []byte) error
-}
-
-// viewerPipeStreamWriter adapts ViewerPipeStream to io.Writer
-type viewerPipeStreamWriter struct {
- sender
-}
-
-func (w viewerPipeStreamWriter) Write(p []byte) (n int, err error) {
- w.Send(p)
- return len(p), nil
-}
-
-func main() {
- flag.Usage = Usage
- runtime := rt.Init(veyron2.NamespaceRoots{"/proxy.envyor.com:8101"})
- log := runtime.Logger()
-
- if flag.NArg() != 1 {
- Usage()
- return
- }
-
- name := flag.Arg(0)
-
- // bind to the p2b service
- s, err := pipetobrowser.BindViewer(name)
- if err != nil {
- log.Errorf("error binding to server: %v", err)
- return
- }
-
- stream, err := s.Pipe(runtime.NewContext())
- if err != nil {
- log.Errorf("failed to pipe to '%s' please ensure p2b service is running in the browser and name is correct.\nERR:%v", name, err)
- return
- }
-
- w := viewerPipeStreamWriter{stream.SendStream()}
-
- _, err = io.Copy(w, os.Stdin)
- if err != nil {
- log.Errorf("failed to copy the stdin pipe to the outgoing stream\nERR:%v", err)
- return
- }
-
- _, err = stream.Finish()
- if err != nil {
- log.Errorf("error finishing stream: %v", err)
- return
- }
-
- fmt.Println("Finished piping to browser! Thanks for using p2b.")
-}
diff --git a/examples/pipetobrowser/package.json b/examples/pipetobrowser/package.json
deleted file mode 100644
index c38e890..0000000
--- a/examples/pipetobrowser/package.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "pipe-to-browser",
- "version": "0.0.1",
- "description": "P2B allows one to pipe anything from shell console to the browser. Data being piped to the browser then is displayed in a graphical and formatted way by a 'viewer' Viewers are pluggable pieces of code that know how to handle and display a stream of data.",
- "dependencies": {
- "veyron": "git+ssh://git@github.com:veyron/veyron.js.git"
- },
- "devDependencies": {
- "jspm": "~0.6.7",
- "vulcanize": "~0.3.0",
- "serve": "~1.4.0",
- "bower": "~1.3.8"
- }
-}
diff --git a/examples/pipetobrowser/services.sh b/examples/pipetobrowser/services.sh
deleted file mode 100755
index a421979..0000000
--- a/examples/pipetobrowser/services.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-source "${VEYRON_ROOT}/environment/scripts/lib/shell.sh"
-
-export PATH="node_modules/.bin:${VEYRON_ROOT}/veyron/go/bin:${PATH}"
-
-main() {
- local -r VEYRON_PROXY_ADDR=proxy.envyor.com:8100
- local -r VEYRON_WSPR_PORT=7776
- local -r HTTP_PORT=8080
- local -r NAMESPACE_ROOT=/proxy.envyor.com:8101
- local -r VEYRON_IDENTITY_PATH=/tmp/p2b_identity
-
- trap "kill -TERM 0" SIGINT SIGTERM EXIT
-
- identity generate veyron_p2b_identity > "${VEYRON_IDENTITY_PATH}"
-
- export VEYRON_IDENTITY="${VEYRON_IDENTITY_PATH}"
- export NAMESPACE_ROOT="${NAMESPACE_ROOT}"
- wsprd --v=1 -alsologtostderr=true -vproxy="${VEYRON_PROXY_ADDR}" --port "${VEYRON_WSPR_PORT}" &
- serve browser/. --port "${HTTP_PORT}" --compress
-
- wait
-}
-
-main "$@"
diff --git a/examples/rockpaperscissors/common/common.go b/examples/rockpaperscissors/common/common.go
deleted file mode 100644
index a8db778..0000000
--- a/examples/rockpaperscissors/common/common.go
+++ /dev/null
@@ -1,111 +0,0 @@
-package common
-
-import (
- "bytes"
- "errors"
- "fmt"
- "math/rand"
- "sync"
- "time"
-
- rps "veyron/examples/rockpaperscissors"
-
- "veyron2/context"
- "veyron2/rt"
- "veyron2/vlog"
-)
-
-type Counter struct {
- value int64
- lock sync.Mutex
-}
-
-func (c *Counter) Add(delta int64) int64 {
- c.lock.Lock()
- defer c.lock.Unlock()
- c.value += delta
- return c.value
-}
-
-func (c *Counter) Value() int64 {
- c.lock.Lock()
- defer c.lock.Unlock()
- return c.value
-}
-
-// FindJudge returns a random rock-paper-scissors judge from the mount table.
-func FindJudge(ctx context.T) (string, error) {
- judges, err := findAll(ctx, "judge")
- if err != nil {
- return "", err
- }
- if len(judges) > 0 {
- return judges[rand.Intn(len(judges))], nil
- }
- return "", errors.New("no judges")
-}
-
-// FindPlayer returns a random rock-paper-scissors player from the mount table.
-func FindPlayer(ctx context.T) (string, error) {
- players, err := findAll(ctx, "player")
- if err != nil {
- return "", err
- }
- if len(players) > 0 {
- return players[rand.Intn(len(players))], nil
- }
- return "", errors.New("no players")
-}
-
-// FindScoreKeepers returns all the rock-paper-scissors score keepers from the
-// mount table.
-func FindScoreKeepers(ctx context.T) ([]string, error) {
- sKeepers, err := findAll(ctx, "scorekeeper")
- if err != nil {
- return nil, err
- }
- return sKeepers, nil
-}
-
-func findAll(ctx context.T, t string) ([]string, error) {
- start := time.Now()
- ns := rt.R().Namespace()
- c, err := ns.Glob(ctx, "rps/"+t+"/*")
- if err != nil {
- vlog.Infof("mt.Glob failed: %v", err)
- return nil, err
- }
- var servers []string
- for e := range c {
- servers = append(servers, e.Name)
- }
- vlog.VI(1).Infof("findAll(%q) elapsed: %s", t, time.Now().Sub(start))
- return servers, nil
-}
-
-func FormatScoreCard(score rps.ScoreCard) string {
- buf := bytes.NewBufferString("")
- var gameType string
- switch score.Opts.GameType {
- case rps.Classic:
- gameType = "Classic"
- case rps.LizardSpock:
- gameType = "LizardSpock"
- default:
- gameType = "Unknown"
- }
- fmt.Fprintf(buf, "Game Type: %s\n", gameType)
- fmt.Fprintf(buf, "Number of rounds: %d\n", score.Opts.NumRounds)
- fmt.Fprintf(buf, "Judge: %s\n", score.Judge)
- fmt.Fprintf(buf, "Player 1: %s\n", score.Players[0])
- fmt.Fprintf(buf, "Player 2: %s\n", score.Players[1])
- for i, r := range score.Rounds {
- roundOffset := time.Duration(r.StartTimeNS - score.StartTimeNS)
- roundTime := time.Duration(r.EndTimeNS - r.StartTimeNS)
- fmt.Fprintf(buf, "Round %2d: Player 1 played %-10q. Player 2 played %-10q. Winner: %d %-28s [%-10s/%-10s]\n",
- i+1, r.Moves[0], r.Moves[1], r.Winner, r.Comment, roundOffset, roundTime)
- }
- fmt.Fprintf(buf, "Winner: %d\n", score.Winner)
- fmt.Fprintf(buf, "Time: %s\n", time.Duration(score.EndTimeNS-score.StartTimeNS))
- return buf.String()
-}
diff --git a/examples/rockpaperscissors/impl/impl.go b/examples/rockpaperscissors/impl/impl.go
deleted file mode 100644
index 7988802..0000000
--- a/examples/rockpaperscissors/impl/impl.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package impl
-
-import (
- "errors"
-
- rps "veyron/examples/rockpaperscissors"
- "veyron2"
- "veyron2/ipc"
- "veyron2/vlog"
-)
-
-// RPS implements rockpaperscissors.RockPaperScissorsService
-type RPS struct {
- player *Player
- judge *Judge
- scoreKeeper *ScoreKeeper
-}
-
-func NewRPS() *RPS {
- return &RPS{player: NewPlayer(), judge: NewJudge(), scoreKeeper: NewScoreKeeper()}
-}
-
-func (r *RPS) Judge() *Judge {
- return r.judge
-}
-
-func (r *RPS) Player() *Player {
- return r.player
-}
-
-func (r *RPS) ScoreKeeper() *ScoreKeeper {
- return r.scoreKeeper
-}
-
-func (r *RPS) CreateGame(ctx ipc.ServerContext, opts rps.GameOptions) (rps.GameID, error) {
- vlog.VI(1).Infof("CreateGame %+v from %s", opts, ctx.RemoteID())
- names := ctx.LocalID().Names()
- if len(names) == 0 {
- return rps.GameID{}, errors.New("no names provided with local ID")
- }
- return r.judge.createGame(names[0], opts)
-}
-
-func (r *RPS) Play(ctx ipc.ServerContext, id rps.GameID, stream rps.JudgeServicePlayStream) (rps.PlayResult, error) {
- vlog.VI(1).Infof("Play %+v from %s", id, ctx.RemoteID())
- names := ctx.RemoteID().Names()
- if len(names) == 0 {
- return rps.PlayResult{}, errors.New("no names provided with remote ID")
- }
- return r.judge.play(ctx, names[0], id, stream)
-}
-
-func (r *RPS) Challenge(ctx ipc.ServerContext, address string, id rps.GameID, opts rps.GameOptions) error {
- vlog.VI(1).Infof("Challenge (%q, %+v, %+v) from %s", address, id, opts, ctx.RemoteID())
- return r.player.challenge(veyron2.RuntimeFromContext(ctx), address, id, opts)
-}
-
-func (r *RPS) Record(ctx ipc.ServerContext, score rps.ScoreCard) error {
- vlog.VI(1).Infof("Record (%+v) from %s", score, ctx.RemoteID())
- return r.scoreKeeper.Record(ctx, score)
-}
diff --git a/examples/rockpaperscissors/impl/impl_test.go b/examples/rockpaperscissors/impl/impl_test.go
deleted file mode 100644
index 6e4971d..0000000
--- a/examples/rockpaperscissors/impl/impl_test.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package impl_test
-
-import (
- "testing"
-
- rps "veyron/examples/rockpaperscissors"
- "veyron/examples/rockpaperscissors/impl"
- mtlib "veyron/services/mounttable/lib"
-
- "veyron2"
- "veyron2/ipc"
- "veyron2/naming"
- "veyron2/rt"
- "veyron2/vlog"
-)
-
-func startMountTable(t *testing.T, runtime veyron2.Runtime) (string, func()) {
- server, err := runtime.NewServer(veyron2.ServesMountTableOpt(true))
- if err != nil {
- t.Fatalf("NewServer() failed: %v", err)
- }
- dispatcher, err := mtlib.NewMountTable("")
-
- protocol, hostname := "tcp", "127.0.0.1:0"
- endpoint, err := server.Listen(protocol, hostname)
- if err != nil {
- t.Fatalf("Listen(%v, %v) failed: %v", protocol, hostname, err)
- }
- if err := server.Serve("", dispatcher); err != nil {
- t.Fatalf("Serve(%v) failed: %v", dispatcher, err)
- }
- address := naming.JoinAddressName(endpoint.String(), "")
- vlog.VI(1).Infof("Mount table running at endpoint: %s", address)
- return address, func() {
- if err := server.Stop(); err != nil {
- t.Fatalf("Stop() failed: %v", err)
- }
- }
-}
-
-func startRockPaperScissors(t *testing.T, rt veyron2.Runtime, mtAddress string) (*impl.RPS, func()) {
- ns := rt.Namespace()
- ns.SetRoots(mtAddress)
- server, err := rt.NewServer()
- if err != nil {
- t.Fatalf("NewServer failed: %v", err)
- }
- rpsService := impl.NewRPS()
-
- if _, err = server.Listen("tcp", "127.0.0.1:0"); err != nil {
- t.Fatalf("Listen failed: %v", err)
- }
- disp := ipc.LeafDispatcher(rps.NewServerRockPaperScissors(rpsService), nil)
- names := []string{"rps/judge/test", "rps/player/test", "rps/scorekeeper/test"}
- for _, n := range names {
- if err := server.Serve(n, disp); err != nil {
- t.Fatalf("Serve(%v) failed: %v", n, err)
- }
- }
- return rpsService, func() {
- if err := server.Stop(); err != nil {
- t.Fatalf("Stop() failed: %v", err)
- }
- }
-}
-
-// TestRockPaperScissorsImpl runs one rock-paper-scissors game and verifies
-// that all the counters are consistent.
-func TestRockPaperScissorsImpl(t *testing.T) {
- runtime := rt.Init()
- defer runtime.Cleanup()
-
- ctx := runtime.NewContext()
-
- mtAddress, mtStop := startMountTable(t, runtime)
- defer mtStop()
- rpsService, rpsStop := startRockPaperScissors(t, runtime, mtAddress)
- defer rpsStop()
-
- const numGames = 10
- for x := 0; x < numGames; x++ {
- if err := rpsService.Player().InitiateGame(ctx); err != nil {
- t.Errorf("Failed to initiate game: %v", err)
- }
- }
- rpsService.Player().WaitUntilIdle()
-
- // For each game, the player plays twice. So, we expect the player to
- // show that it played 2×numGames, and won numGames.
- played, won := rpsService.Player().Stats()
- if want, got := int64(2*numGames), played; want != got {
- t.Errorf("Unexpected number of played games. Got %d, want %d", got, want)
- }
- if want, got := int64(numGames), won; want != got {
- t.Errorf("Unexpected number of won games. Got %d, want %d", got, want)
- }
-
- // The Judge ran every game.
- if want, got := int64(numGames), rpsService.Judge().Stats(); want != got {
- t.Errorf("Unexpected number of games run. Got %d, want %d", got, want)
- }
-
- // The Score Keeper received one score card per game.
- if want, got := int64(numGames), rpsService.ScoreKeeper().Stats(); want != got {
- t.Errorf("Unexpected number of score cards. Got %d, want %d", got, want)
- }
-}
diff --git a/examples/rockpaperscissors/impl/judge.go b/examples/rockpaperscissors/impl/judge.go
deleted file mode 100644
index 0b1a774..0000000
--- a/examples/rockpaperscissors/impl/judge.go
+++ /dev/null
@@ -1,350 +0,0 @@
-package impl
-
-import (
- "errors"
- "fmt"
- "strconv"
- "sync"
- "time"
-
- rps "veyron/examples/rockpaperscissors"
- "veyron/examples/rockpaperscissors/common"
-
- "veyron2/context"
- "veyron2/vlog"
-)
-
-var (
- errBadGameID = errors.New("requested gameID doesn't exist")
- errTooManyPlayers = errors.New("all players are already seated")
-)
-
-type Judge struct {
- lock sync.Mutex
- games map[rps.GameID]*gameInfo
- gamesRun common.Counter
-}
-
-type sendStream interface {
- Send(item rps.JudgeAction) error
-}
-
-type gameInfo struct {
- id rps.GameID
- startTime time.Time
- score rps.ScoreCard
- streams []sendStream
- playerIn chan playerInput
- playerOut []chan rps.JudgeAction
- scoreChan chan scoreData
-}
-
-func (g *gameInfo) moveOptions() []string {
- switch g.score.Opts.GameType {
- case rps.LizardSpock:
- return []string{"rock", "paper", "scissors", "lizard", "spock"}
- default:
- return []string{"rock", "paper", "scissors"}
- }
-}
-
-func (g *gameInfo) validMove(m string) bool {
- for _, x := range g.moveOptions() {
- if x == m {
- return true
- }
- }
- return false
-}
-
-type playerInput struct {
- player int
- action rps.PlayerAction
-}
-
-type scoreData struct {
- err error
- score rps.ScoreCard
-}
-
-func NewJudge() *Judge {
- return &Judge{games: make(map[rps.GameID]*gameInfo)}
-}
-
-func (j *Judge) Stats() int64 {
- return j.gamesRun.Value()
-}
-
-// createGame handles a request to create a new game.
-func (j *Judge) createGame(ownName string, opts rps.GameOptions) (rps.GameID, error) {
- vlog.VI(1).Infof("createGame called")
- score := rps.ScoreCard{Opts: opts, Judge: ownName}
- now := time.Now()
- id := rps.GameID{ID: strconv.FormatInt(now.UnixNano(), 16)}
-
- j.lock.Lock()
- defer j.lock.Unlock()
- for k, v := range j.games {
- if now.Sub(v.startTime) > 1*time.Hour {
- vlog.Infof("Removing stale game ID %v", k)
- delete(j.games, k)
- }
- }
- j.games[id] = &gameInfo{
- id: id,
- startTime: now,
- score: score,
- playerIn: make(chan playerInput),
- playerOut: []chan rps.JudgeAction{
- make(chan rps.JudgeAction),
- make(chan rps.JudgeAction),
- },
- scoreChan: make(chan scoreData),
- }
- return id, nil
-}
-
-// play interacts with a player for the duration of a game.
-func (j *Judge) play(ctx context.T, name string, id rps.GameID, stream rps.JudgeServicePlayStream) (rps.PlayResult, error) {
- vlog.VI(1).Infof("play from %q for %v", name, id)
- nilResult := rps.PlayResult{}
-
- pIn, pOut, s, err := j.gameChannels(id)
- if err != nil {
- return nilResult, err
- }
- playerNum, err := j.addPlayer(name, id, stream)
- if err != nil {
- return nilResult, err
- }
- vlog.VI(1).Infof("This is player %d", playerNum)
-
- // Send all user input to the player input channel.
- done := make(chan struct{})
- defer close(done)
- go func() {
- rStream := stream.RecvStream()
- for rStream.Advance() {
- action := rStream.Value()
- select {
- case pIn <- playerInput{player: playerNum, action: action}:
- case <-done:
- return
- }
- }
- select {
- case pIn <- playerInput{player: playerNum, action: rps.PlayerAction{Quit: true}}:
- case <-done:
- }
- }()
- // Send all the output to the user.
- go func() {
- for packet := range pOut[playerNum-1] {
- if err := stream.SendStream().Send(packet); err != nil {
- vlog.Infof("error sending to player stream: %v", err)
- }
- }
- }()
- defer close(pOut[playerNum-1])
-
- pOut[playerNum-1] <- rps.JudgeAction{PlayerNum: int32(playerNum)}
-
- // When the second player connects, we start the game.
- if playerNum == 2 {
- go j.manageGame(ctx, id)
- }
- // Wait for the ScoreCard.
- scoreData := <-s
- if scoreData.err != nil {
- return rps.PlayResult{}, scoreData.err
- }
- return rps.PlayResult{YouWon: scoreData.score.Winner == rps.WinnerTag(playerNum)}, nil
-}
-
-func (j *Judge) manageGame(ctx context.T, id rps.GameID) {
- j.gamesRun.Add(1)
- j.lock.Lock()
- info, exists := j.games[id]
- if !exists {
- e := scoreData{err: errBadGameID}
- info.scoreChan <- e
- info.scoreChan <- e
- return
- }
- delete(j.games, id)
- j.lock.Unlock()
-
- // Inform each player of their opponent's name.
- for p := 0; p < 2; p++ {
- opp := 1 - p
- info.playerOut[p] <- rps.JudgeAction{OpponentName: info.score.Players[opp]}
- }
-
- win1, win2 := 0, 0
- goal := int(info.score.Opts.NumRounds)
- // Play until one player has won 'goal' times.
- for win1 < goal && win2 < goal {
- round, err := j.playOneRound(info)
- if err != nil {
- err := scoreData{err: err}
- info.scoreChan <- err
- info.scoreChan <- err
- return
- }
- if round.Winner == rps.Player1 {
- win1++
- } else if round.Winner == rps.Player2 {
- win2++
- }
- info.score.Rounds = append(info.score.Rounds, round)
- }
- if win1 > win2 {
- info.score.Winner = rps.Player1
- } else {
- info.score.Winner = rps.Player2
- }
-
- info.score.StartTimeNS = info.startTime.UnixNano()
- info.score.EndTimeNS = time.Now().UnixNano()
-
- // Send the score card to the players.
- action := rps.JudgeAction{Score: info.score}
- for _, p := range info.playerOut {
- p <- action
- }
-
- // Send the score card to the score keepers.
- keepers, err := common.FindScoreKeepers(ctx)
- if err != nil || len(keepers) == 0 {
- vlog.Infof("No score keepers: %v", err)
- return
- }
- done := make(chan bool)
- for _, k := range keepers {
- go j.sendScore(ctx, k, info.score, done)
- }
- for _ = range keepers {
- <-done
- }
-
- info.scoreChan <- scoreData{score: info.score}
- info.scoreChan <- scoreData{score: info.score}
-}
-
-func (j *Judge) playOneRound(info *gameInfo) (rps.Round, error) {
- round := rps.Round{StartTimeNS: time.Now().UnixNano()}
- action := rps.JudgeAction{MoveOptions: info.moveOptions()}
- for _, p := range info.playerOut {
- p <- action
- }
- for x := 0; x < 2; x++ {
- in := <-info.playerIn
- if in.action.Quit {
- return round, fmt.Errorf("player %d quit the game", in.player)
- }
- if !info.validMove(in.action.Move) {
- return round, fmt.Errorf("player %d made an invalid move: %s", in.player, in.action.Move)
- }
- if len(round.Moves[in.player-1]) > 0 {
- return round, fmt.Errorf("player %d played twice in the same round!", in.player)
- }
- round.Moves[in.player-1] = in.action.Move
- }
- round.Winner, round.Comment = j.compareMoves(round.Moves[0], round.Moves[1])
- vlog.VI(1).Infof("Player 1 played %q. Player 2 played %q. Winner: %d %s", round.Moves[0], round.Moves[1], round.Winner, round.Comment)
-
- action = rps.JudgeAction{RoundResult: round}
- for _, p := range info.playerOut {
- p <- action
- }
- round.EndTimeNS = time.Now().UnixNano()
- return round, nil
-}
-
-func (j *Judge) addPlayer(name string, id rps.GameID, stream rps.JudgeServicePlayStream) (int, error) {
- j.lock.Lock()
- defer j.lock.Unlock()
-
- info, exists := j.games[id]
- if !exists {
- return 0, errBadGameID
- }
- if len(info.streams) == 2 {
- return 0, errTooManyPlayers
- }
- info.score.Players = append(info.score.Players, name)
- info.streams = append(info.streams, stream.SendStream())
- return len(info.streams), nil
-}
-
-func (j *Judge) gameChannels(id rps.GameID) (chan playerInput, []chan rps.JudgeAction, chan scoreData, error) {
- j.lock.Lock()
- defer j.lock.Unlock()
- info, exists := j.games[id]
- if !exists {
- return nil, nil, nil, errBadGameID
- }
- return info.playerIn, info.playerOut, info.scoreChan, nil
-}
-
-func (j *Judge) sendScore(ctx context.T, address string, score rps.ScoreCard, done chan bool) error {
- defer func() { done <- true }()
- k, err := rps.BindRockPaperScissors(address)
- if err != nil {
- vlog.Infof("BindRockPaperScissors: %v", err)
- return err
- }
- err = k.Record(ctx, score)
- if err != nil {
- vlog.Infof("Record: %v", err)
- return err
- }
- return nil
-}
-
-var moveComments = map[string]string{
- "lizard-paper": "lizard eats paper",
- "lizard-rock": "rock crushes lizard",
- "lizard-scissors": "scissors decapitates lizard",
- "lizard-spock": "lizard poisons spock",
- "paper-rock": "paper covers rock",
- "paper-scissors": "scissors cuts paper",
- "paper-spock": "paper disproves spock",
- "rock-scissors": "rock crushes scissors",
- "rock-spock": "spock vaporizes rock",
- "scissors-spock": "spock smashes scissors",
-}
-
-func (j *Judge) compareMoves(m1, m2 string) (winner rps.WinnerTag, comment string) {
- if m1 < m2 {
- comment = moveComments[m1+"-"+m2]
- } else {
- comment = moveComments[m2+"-"+m1]
- }
- if m1 == m2 {
- winner = rps.Draw
- return
- }
- if m1 == "rock" && (m2 == "scissors" || m2 == "lizard") {
- winner = rps.Player1
- return
- }
- if m1 == "paper" && (m2 == "rock" || m2 == "spock") {
- winner = rps.Player1
- return
- }
- if m1 == "scissors" && (m2 == "paper" || m2 == "lizard") {
- winner = rps.Player1
- return
- }
- if m1 == "lizard" && (m2 == "paper" || m2 == "spock") {
- winner = rps.Player1
- return
- }
- if m1 == "spock" && (m2 == "scissors" || m2 == "rock") {
- winner = rps.Player1
- return
- }
- winner = rps.Player2
- return
-}
diff --git a/examples/rockpaperscissors/impl/player.go b/examples/rockpaperscissors/impl/player.go
deleted file mode 100644
index 4d845c8..0000000
--- a/examples/rockpaperscissors/impl/player.go
+++ /dev/null
@@ -1,159 +0,0 @@
-package impl
-
-import (
- "math/rand"
- "time"
-
- rps "veyron/examples/rockpaperscissors"
- "veyron/examples/rockpaperscissors/common"
-
- "veyron2"
- "veyron2/context"
- "veyron2/vlog"
-)
-
-type Player struct {
- gamesPlayed common.Counter
- gamesWon common.Counter
- gamesInProgress common.Counter
-}
-
-func NewPlayer() *Player {
- return &Player{}
-}
-
-func (p *Player) Stats() (played, won int64) {
- played = p.gamesPlayed.Value()
- won = p.gamesWon.Value()
- return
-}
-
-// only used by tests.
-func (p *Player) WaitUntilIdle() {
- for p.gamesInProgress.Value() != 0 {
- time.Sleep(10 * time.Millisecond)
- }
-}
-
-func (p *Player) InitiateGame(ctx context.T) error {
- judge, err := common.FindJudge(ctx)
- if err != nil {
- vlog.Infof("FindJudge: %v", err)
- return err
- }
- gameID, gameOpts, err := p.createGame(ctx, judge)
- if err != nil {
- vlog.Infof("createGame: %v", err)
- return err
- }
- vlog.VI(1).Infof("Created gameID %q on %q", gameID, judge)
-
- for {
- opponent, err := common.FindPlayer(ctx)
- if err != nil {
- vlog.Infof("FindPlayer: %v", err)
- return err
- }
- vlog.VI(1).Infof("chosen opponent is %q", opponent)
- if err = p.sendChallenge(ctx, opponent, judge, gameID, gameOpts); err == nil {
- break
- }
- vlog.Infof("sendChallenge: %v", err)
- }
- result, err := p.playGame(ctx, judge, gameID)
- if err != nil {
- vlog.Infof("playGame: %v", err)
- return err
- }
- if result.YouWon {
- vlog.VI(1).Info("Game result: I won! :)")
- } else {
- vlog.VI(1).Info("Game result: I lost :(")
- }
- return nil
-}
-
-func (p *Player) createGame(ctx context.T, server string) (rps.GameID, rps.GameOptions, error) {
- j, err := rps.BindRockPaperScissors(server)
- if err != nil {
- return rps.GameID{}, rps.GameOptions{}, err
- }
- numRounds := 3 + rand.Intn(3)
- gameType := rps.Classic
- if rand.Intn(2) == 1 {
- gameType = rps.LizardSpock
- }
- gameOpts := rps.GameOptions{NumRounds: int32(numRounds), GameType: gameType}
- gameId, err := j.CreateGame(ctx, gameOpts)
- return gameId, gameOpts, err
-}
-
-func (p *Player) sendChallenge(ctx context.T, opponent, judge string, gameID rps.GameID, gameOpts rps.GameOptions) error {
- o, err := rps.BindRockPaperScissors(opponent)
- if err != nil {
- return err
- }
- return o.Challenge(ctx, judge, gameID, gameOpts)
-}
-
-// challenge receives an incoming challenge and starts to play a new game.
-// Note that the new game will occur in a new context.
-func (p *Player) challenge(rt veyron2.Runtime, judge string, gameID rps.GameID, _ rps.GameOptions) error {
- vlog.VI(1).Infof("challenge received: %s %v", judge, gameID)
- go p.playGame(rt.NewContext(), judge, gameID)
- return nil
-}
-
-// playGame plays an entire game, which really only consists of reading
-// commands from the server, and picking a random "move" when asked to.
-func (p *Player) playGame(outer context.T, judge string, gameID rps.GameID) (rps.PlayResult, error) {
- ctx, cancel := outer.WithTimeout(10 * time.Minute)
- defer cancel()
- p.gamesInProgress.Add(1)
- defer p.gamesInProgress.Add(-1)
- j, err := rps.BindRockPaperScissors(judge)
- if err != nil {
- return rps.PlayResult{}, err
- }
- game, err := j.Play(ctx, gameID)
- if err != nil {
- return rps.PlayResult{}, err
- }
- rStream := game.RecvStream()
- sender := game.SendStream()
- for rStream.Advance() {
- in := rStream.Value()
- if in.PlayerNum > 0 {
- vlog.VI(1).Infof("I'm player %d", in.PlayerNum)
- }
- if len(in.OpponentName) > 0 {
- vlog.VI(1).Infof("My opponent is %q", in.OpponentName)
- }
- if len(in.MoveOptions) > 0 {
- n := rand.Intn(len(in.MoveOptions))
- vlog.VI(1).Infof("My turn to play. Picked %q from %v", in.MoveOptions[n], in.MoveOptions)
- if err := sender.Send(rps.PlayerAction{Move: in.MoveOptions[n]}); err != nil {
- return rps.PlayResult{}, err
- }
- }
- if len(in.RoundResult.Moves[0]) > 0 {
- vlog.VI(1).Infof("Player 1 played %q. Player 2 played %q. Winner: %v %s",
- in.RoundResult.Moves[0], in.RoundResult.Moves[1], in.RoundResult.Winner, in.RoundResult.Comment)
- }
- if len(in.Score.Players) > 0 {
- vlog.VI(1).Infof("Score card: %s", common.FormatScoreCard(in.Score))
- }
- }
-
- if err := rStream.Err(); err != nil {
- vlog.Infof("stream error: %v", err)
- } else {
- vlog.VI(1).Infof("Game Ended")
- }
- result, err := game.Finish()
- p.gamesPlayed.Add(1)
- if err == nil && result.YouWon {
- p.gamesWon.Add(1)
- }
- return result, err
-}
diff --git a/examples/rockpaperscissors/impl/scorekeeper.go b/examples/rockpaperscissors/impl/scorekeeper.go
deleted file mode 100644
index 6398e76..0000000
--- a/examples/rockpaperscissors/impl/scorekeeper.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package impl
-
-import (
- rps "veyron/examples/rockpaperscissors"
- "veyron/examples/rockpaperscissors/common"
-
- "veyron2/ipc"
- "veyron2/vlog"
-)
-
-type ScoreKeeper struct {
- numRecords common.Counter
-}
-
-func NewScoreKeeper() *ScoreKeeper {
- return &ScoreKeeper{}
-}
-
-func (k *ScoreKeeper) Stats() int64 {
- return k.numRecords.Value()
-}
-
-func (k *ScoreKeeper) Record(ctx ipc.ServerContext, score rps.ScoreCard) error {
- vlog.VI(1).Infof("Received ScoreCard from %s:", ctx.RemoteID())
- vlog.VI(1).Info(common.FormatScoreCard(score))
- k.numRecords.Add(1)
- return nil
-}
diff --git a/examples/rockpaperscissors/rpsbot/main.go b/examples/rockpaperscissors/rpsbot/main.go
deleted file mode 100644
index 67af3f2..0000000
--- a/examples/rockpaperscissors/rpsbot/main.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// rpsbot is a binary that runs the fully automated implementation of the
-// RockPaperScissors service, which includes all three roles involved in the
-// game of rock-paper-scissors. It publishes itself as player, judge, and
-// scorekeeper. Then, it initiates games with other players, in a loop. As soon
-// as one game is over, it starts a new one.
-package main
-
-import (
- "flag"
- "fmt"
- "math/rand"
- "os"
- "time"
-
- rps "veyron/examples/rockpaperscissors"
- "veyron/examples/rockpaperscissors/impl"
- "veyron/lib/signals"
- sflag "veyron/security/flag"
- "veyron/services/mgmt/debug"
-
- "veyron2"
- "veyron2/context"
- "veyron2/ipc"
- "veyron2/rt"
- "veyron2/security"
- "veyron2/vlog"
-)
-
-var (
- // TODO(rthellend): Remove the protocol and address flags when the config
- // manager is working.
- protocol = flag.String("protocol", "tcp", "protocol to listen on. For example, set to 'veyron' and set --address to the endpoint/name of a proxy to have this tunnel service proxied.")
- address = flag.String("address", ":0", "address to listen on")
-)
-
-// The dispatcher returns the RPS invoker unless a suffix is used, or the method
-// called is Glob. This is intended to exercise the DebugServer code.
-type dispatcher struct {
- rpsInvoker ipc.Invoker
- auth security.Authorizer
- debug ipc.Dispatcher
-}
-
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
- if len(suffix) == 0 && method != "Glob" {
- return d.rpsInvoker, d.auth, nil
- }
- return d.debug.Lookup(suffix, method)
-}
-
-func newDispatcher(runtime veyron2.Runtime, service *impl.RPS, auth security.Authorizer) *dispatcher {
- return &dispatcher{
- rpsInvoker: ipc.ReflectInvoker(rps.NewServerRockPaperScissors(service)),
- auth: auth,
- debug: debug.NewDispatcher(runtime, vlog.Log.LogDir(), auth),
- }
-}
-
-func main() {
- r := rt.Init()
- defer r.Cleanup()
- server, err := r.NewServer()
- if err != nil {
- vlog.Fatalf("NewServer failed: %v", err)
- }
- defer server.Stop()
-
- rand.Seed(time.Now().UnixNano())
- rpsService := impl.NewRPS()
-
- dispatcher := newDispatcher(r, rpsService, sflag.NewAuthorizerOrDie())
-
- ep, err := server.Listen(*protocol, *address)
- if err != nil {
- vlog.Fatalf("Listen(%q, %q) failed: %v", "tcp", *address, err)
- }
- hostname, err := os.Hostname()
- if err != nil {
- vlog.Fatalf("os.Hostname failed: %v", err)
- }
- names := []string{
- fmt.Sprintf("rps/judge/%s", hostname),
- fmt.Sprintf("rps/player/%s", hostname),
- fmt.Sprintf("rps/scorekeeper/%s", hostname),
- }
- for _, n := range names {
- if err := server.Serve(n, dispatcher); err != nil {
- vlog.Fatalf("Serve(%v) failed: %v", n, err)
- }
- }
- vlog.Infof("Listening on endpoint /%s (published as %v)", ep, names)
-
- ctx := r.NewContext()
- go initiateGames(ctx, rpsService)
- <-signals.ShutdownOnSignals()
-}
-
-func initiateGames(ctx context.T, rpsService *impl.RPS) {
- for {
- if err := rpsService.Player().InitiateGame(ctx); err != nil {
- vlog.Infof("Failed to initiate game: %v", err)
- }
- }
-}
diff --git a/examples/rockpaperscissors/rpsplayercli/main.go b/examples/rockpaperscissors/rpsplayercli/main.go
deleted file mode 100644
index 0a2828c..0000000
--- a/examples/rockpaperscissors/rpsplayercli/main.go
+++ /dev/null
@@ -1,307 +0,0 @@
-// rpsplayer is a command-line implementation of the Player service that allows
-// a human player to join the game.
-package main
-
-import (
- "errors"
- "flag"
- "fmt"
- "os"
- "sort"
- "strings"
- "sync"
- "time"
-
- rps "veyron/examples/rockpaperscissors"
- "veyron/examples/rockpaperscissors/common"
- sflag "veyron/security/flag"
-
- "veyron2"
- "veyron2/context"
- "veyron2/ipc"
- "veyron2/rt"
- "veyron2/vlog"
-)
-
-var (
- // TODO(rthellend): Remove the protocol and address flags when the config
- // manager is working.
- protocol = flag.String("protocol", "tcp", "protocol to listen on. For example, set to 'veyron' and set --address to the endpoint/name of a proxy to have this tunnel service proxied.")
- address = flag.String("address", ":0", "address to listen on")
-)
-
-func main() {
- r := rt.Init()
- defer r.Cleanup()
-
- for {
- ctx := r.NewContext()
- if selectOne([]string{"Initiate Game", "Wait For Challenge"}) == 0 {
- initiateGame(ctx)
- } else {
- fmt.Println("Waiting to receive a challenge...")
- game := recvChallenge(r)
- playGame(ctx, game.address, game.id)
- }
- if selectOne([]string{"Play Again", "Quit"}) == 1 {
- break
- }
- }
-}
-
-type gameChallenge struct {
- address string
- id rps.GameID
- opts rps.GameOptions
-}
-
-// impl is a PlayerService implementation that prompts the user to accept or
-// decline challenges. While waiting for a reply from the user, any incoming
-// challenges are auto-declined.
-type impl struct {
- ch chan gameChallenge
- decline bool
- lock sync.Mutex
-}
-
-func (i *impl) setDecline(v bool) bool {
- i.lock.Lock()
- defer i.lock.Unlock()
- prev := i.decline
- i.decline = v
- return prev
-}
-
-func (i *impl) Challenge(ctx ipc.ServerContext, address string, id rps.GameID, opts rps.GameOptions) error {
- vlog.VI(1).Infof("Challenge (%q, %+v) from %s", address, id, ctx.RemoteID())
- // When setDecline(true) returns, future challenges will be declined.
- // Whether the current challenge should be considered depends on the
- // previous state. If 'decline' was already true, we need to decline
- // this challenge. It 'decline' was false, this is the first challenge
- // that we should process.
- if i.setDecline(true) {
- return errors.New("player is busy")
- }
- fmt.Println()
- fmt.Printf("Challenge received from %s for a %d-round ", ctx.RemoteID(), opts.NumRounds)
- switch opts.GameType {
- case rps.Classic:
- fmt.Print("Classic ")
- case rps.LizardSpock:
- fmt.Print("Lizard-Spock ")
- default:
- }
- fmt.Println("Game.")
- if selectOne([]string{"Accept", "Decline"}) == 0 {
- i.ch <- gameChallenge{address, id, opts}
- return nil
- }
- // Start considering challenges again.
- i.setDecline(false)
- return errors.New("player declined challenge")
-}
-
-// recvChallenge runs a server until a game challenge is accepted by the user.
-// The server is stopped afterwards.
-func recvChallenge(rt veyron2.Runtime) gameChallenge {
- server, err := rt.NewServer()
- if err != nil {
- vlog.Fatalf("NewServer failed: %v", err)
- }
- ch := make(chan gameChallenge)
-
- dispatcher := ipc.LeafDispatcher(rps.NewServerPlayer(&impl{ch: ch}), sflag.NewAuthorizerOrDie())
- ep, err := server.Listen(*protocol, *address)
- if err != nil {
- vlog.Fatalf("Listen(%q, %q) failed: %v", "tcp", *address, err)
- }
- hostname, err := os.Hostname()
- if err != nil {
- vlog.Fatalf("os.Hostname failed: %v", err)
- }
- if err := server.Serve(fmt.Sprintf("rps/player/%s@%s", os.Getenv("USER"), hostname), dispatcher); err != nil {
- vlog.Fatalf("Serve failed: %v", err)
- }
- vlog.Infof("Listening on endpoint /%s", ep)
- result := <-ch
- server.Stop()
- return result
-}
-
-// initiateGame initiates a new game by getting a list of judges and players,
-// and asking the user to select one of each, to select the game options, what
-// to play, etc.
-func initiateGame(ctx context.T) error {
- jChan := make(chan []string)
- oChan := make(chan []string)
- go findAll(ctx, "judge", jChan)
- go findAll(ctx, "player", oChan)
-
- fmt.Println("Looking for available participants...")
- judges := <-jChan
- opponents := <-oChan
- fmt.Println()
- if len(judges) == 0 || len(opponents) == 0 {
- return errors.New("no one to play with")
- }
-
- fmt.Println("Choose a judge:")
- j := selectOne(judges)
- fmt.Println("Choose an opponent:")
- o := selectOne(opponents)
- fmt.Println("Choose the type of rock-paper-scissors game would you like to play:")
- gameType := selectOne([]string{"Classic", "LizardSpock"})
- fmt.Println("Choose the number of rounds required to win:")
- numRounds := selectOne([]string{"1", "2", "3", "4", "5", "6"}) + 1
- gameOpts := rps.GameOptions{NumRounds: int32(numRounds), GameType: rps.GameTypeTag(gameType)}
-
- gameID, err := createGame(ctx, judges[j], gameOpts)
- if err != nil {
- vlog.Infof("createGame: %v", err)
- return err
- }
- for {
- err := sendChallenge(ctx, opponents[o], judges[j], gameID, gameOpts)
- if err == nil {
- break
- }
- fmt.Printf("Challenge was declined by %s (%v)\n", opponents[o], err)
- fmt.Println("Choose another opponent:")
- o = selectOne(opponents)
- }
- fmt.Println("Joining the game...")
-
- if _, err = playGame(ctx, judges[j], gameID); err != nil {
- vlog.Infof("playGame: %v", err)
- return err
- }
- return nil
-}
-
-func createGame(ctx context.T, server string, opts rps.GameOptions) (rps.GameID, error) {
- j, err := rps.BindRockPaperScissors(server)
- if err != nil {
- return rps.GameID{}, err
- }
- return j.CreateGame(ctx, opts)
-}
-
-func sendChallenge(ctx context.T, opponent, judge string, gameID rps.GameID, gameOpts rps.GameOptions) error {
- o, err := rps.BindRockPaperScissors(opponent)
- if err != nil {
- return err
- }
- return o.Challenge(ctx, judge, gameID, gameOpts)
-}
-
-func playGame(outer context.T, judge string, gameID rps.GameID) (rps.PlayResult, error) {
- ctx, cancel := outer.WithTimeout(10 * time.Minute)
- defer cancel()
- fmt.Println()
- j, err := rps.BindRockPaperScissors(judge)
- if err != nil {
- return rps.PlayResult{}, err
- }
-
- game, err := j.Play(ctx, gameID)
- if err != nil {
- return rps.PlayResult{}, err
- }
- var playerNum int32
- rStream := game.RecvStream()
- for rStream.Advance() {
- in := rStream.Value()
- if in.PlayerNum > 0 {
- playerNum = in.PlayerNum
- fmt.Printf("You are player %d\n", in.PlayerNum)
- }
- if len(in.OpponentName) > 0 {
- fmt.Printf("Your opponent is %q\n", in.OpponentName)
- }
- if len(in.RoundResult.Moves[0]) > 0 {
- if playerNum != 1 && playerNum != 2 {
- vlog.Fatalf("invalid playerNum: %d", playerNum)
- }
- fmt.Printf("You played %q\n", in.RoundResult.Moves[playerNum-1])
- fmt.Printf("Your opponent played %q\n", in.RoundResult.Moves[2-playerNum])
- if len(in.RoundResult.Comment) > 0 {
- fmt.Printf(">>> %s <<<\n", strings.ToUpper(in.RoundResult.Comment))
- }
- if in.RoundResult.Winner == 0 {
- fmt.Println("----- It's a draw -----")
- } else if rps.WinnerTag(playerNum) == in.RoundResult.Winner {
- fmt.Println("***** You WIN *****")
- } else {
- fmt.Println("##### You LOSE #####")
- }
- }
- if len(in.MoveOptions) > 0 {
- fmt.Println()
- fmt.Println("Choose your weapon:")
- m := selectOne(in.MoveOptions)
- if err := game.SendStream().Send(rps.PlayerAction{Move: in.MoveOptions[m]}); err != nil {
- return rps.PlayResult{}, err
- }
- }
- if len(in.Score.Players) > 0 {
- fmt.Println()
- fmt.Println("==== GAME SUMMARY ====")
- fmt.Print(common.FormatScoreCard(in.Score))
- fmt.Println("======================")
- if rps.WinnerTag(playerNum) == in.Score.Winner {
- fmt.Println("You won! :)")
- } else {
- fmt.Println("You lost! :(")
- }
- }
- }
- if err := rStream.Err(); err == nil {
- fmt.Println("Game Ended")
- } else {
- vlog.Infof("stream error: %v", err)
- }
-
- return game.Finish()
-}
-
-func selectOne(choices []string) (choice int) {
- if len(choices) == 0 {
- vlog.Fatal("No options to choose from!")
- }
- fmt.Println()
- for i, x := range choices {
- fmt.Printf(" %d. %s\n", i+1, x)
- }
- fmt.Println()
- for {
- if len(choices) == 1 {
- fmt.Print("Select one [1] --> ")
- } else {
- fmt.Printf("Select one [1-%d] --> ", len(choices))
- }
- fmt.Scanf("%d", &choice)
- if choice >= 1 && choice <= len(choices) {
- choice -= 1
- break
- }
- }
- fmt.Println()
- return
-}
-
-func findAll(ctx context.T, t string, out chan []string) {
- ns := rt.R().Namespace()
- var result []string
- c, err := ns.Glob(ctx, "rps/"+t+"/*")
- if err != nil {
- vlog.Infof("ns.Glob failed: %v", err)
- out <- result
- return
- }
- for e := range c {
- fmt.Print(".")
- result = append(result, e.Name)
- }
- sort.Strings(result)
- out <- result
-}
diff --git a/examples/rockpaperscissors/rpsscorekeeper/main.go b/examples/rockpaperscissors/rpsscorekeeper/main.go
deleted file mode 100644
index 46caeb9..0000000
--- a/examples/rockpaperscissors/rpsscorekeeper/main.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// rpsscorekeeper is a simple implementation of the ScoreKeeper service. It
-// publishes itself as a score keeper for the rock-paper-scissors game and
-// prints out all the score cards it receives to stdout.
-package main
-
-import (
- "flag"
- "fmt"
- "os"
-
- rps "veyron/examples/rockpaperscissors"
- "veyron/examples/rockpaperscissors/common"
- sflag "veyron/security/flag"
-
- "veyron2/ipc"
- "veyron2/rt"
- "veyron2/vlog"
-)
-
-var (
- // TODO(rthellend): Remove the protocol and address flags when the config
- // manager is working.
- protocol = flag.String("protocol", "tcp", "protocol to listen on. For example, set to 'veyron' and set --address to the endpoint/name of a proxy to have this tunnel service proxied.")
- address = flag.String("address", ":0", "address to listen on")
-)
-
-type impl struct {
- ch chan rps.ScoreCard
-}
-
-func (i *impl) Record(ctx ipc.ServerContext, score rps.ScoreCard) error {
- vlog.VI(1).Infof("Record (%+v) from %s", score, ctx.RemoteID())
- i.ch <- score
- return nil
-}
-
-func main() {
- r := rt.Init()
- defer r.Cleanup()
- server, err := r.NewServer()
- if err != nil {
- vlog.Fatalf("NewServer failed: %v", err)
- }
- defer server.Stop()
-
- ch := make(chan rps.ScoreCard)
- rpsService := &impl{ch}
-
- dispatcher := ipc.LeafDispatcher(rps.NewServerScoreKeeper(rpsService), sflag.NewAuthorizerOrDie())
- ep, err := server.Listen(*protocol, *address)
- if err != nil {
- vlog.Fatalf("Listen(%q, %q) failed: %v", "tcp", *address, err)
- }
- hostname, err := os.Hostname()
- if err != nil {
- vlog.Fatalf("os.Hostname failed: %v", err)
- }
- if err := server.Serve(fmt.Sprintf("rps/scorekeeper/%s", hostname), dispatcher); err != nil {
- vlog.Fatalf("Serve failed: %v", err)
- }
- vlog.Infof("Listening on endpoint /%s", ep)
-
- for score := range ch {
- fmt.Print("======================\n", common.FormatScoreCard(score))
- }
-}
diff --git a/examples/rockpaperscissors/service.vdl b/examples/rockpaperscissors/service.vdl
deleted file mode 100644
index 1b927b9..0000000
--- a/examples/rockpaperscissors/service.vdl
+++ /dev/null
@@ -1,102 +0,0 @@
-package rockpaperscissors
-
-// RockPaperScissors describes the interface for playing a game of
-// Rock-Paper-Scissors. (http://en.wikipedia.org/wiki/Rock-paper-scissors)
-// There are three different roles in the game:
-//
-// 1. Judge: A judge enforces the rules of the game and decides who the
-// winner is. At the end of the game, the judge reports the final score
-// to all the score keepers.
-// 2. Player: A player can ask a judge to start a new game, it can challenge
-// another player, and it can play a game.
-// 3. ScoreKeeper: A score keeper receives the final score for a game after it
-// ended.
-
-type RockPaperScissors interface {
- Judge
- Player
- ScoreKeeper
-}
-
-type Judge interface {
- // CreateGame creates a new game with the given game options and returns a game
- // identifier that can be used by the players to join the game.
- CreateGame(Opts GameOptions) (GameID, error)
- // Play lets a player join an existing game and play.
- Play(ID GameID) stream<PlayerAction,JudgeAction> (PlayResult, error)
-}
-
-// A GameID is used to uniquely identify a game within one Judge.
-type GameID struct {
- ID string
-}
-
-// GameOptions specifies the parameters of a game.
-type GameOptions struct {
- NumRounds int32 // The number of rounds that a player must win to win the game.
- GameType GameTypeTag // The type of game to play: Classic or LizardSpock.
-}
-
-type GameTypeTag byte
-const (
- Classic = GameTypeTag(0) // Rock-Paper-Scissors
- LizardSpock = GameTypeTag(1) // Rock-Paper-Scissors-Lizard-Spock
-)
-
-type PlayerAction struct {
- Move string // The move that the player wants to make.
- Quit bool // Whether the player wants to quit the game.
-}
-
-type JudgeAction struct {
- PlayerNum int32 // The player's number.
- OpponentName string // The name of the opponent.
- MoveOptions []string // A list of allowed moves that the player must choose from. Not always present.
- RoundResult Round // The result of the previous round. Not always present.
- Score ScoreCard // The result of the game. Not always present.
-}
-
-// Round represents the state of a round.
-type Round struct {
- Moves [2]string // Each player's move.
- Comment string // A text comment from judge about the round.
- Winner WinnerTag // Who won the round.
- StartTimeNS int64 // The time at which the round started.
- EndTimeNS int64 // The time at which the round ended.
-}
-
-// WinnerTag is a type used to indicate whether a round or a game was a draw,
-// was won by player 1 or was won by player 2.
-type WinnerTag byte
-const (
- Draw = WinnerTag(0)
- Player1 = WinnerTag(1)
- Player2 = WinnerTag(2)
-)
-
-// PlayResult is the value returned by the Play method. It indicates the outcome of the game.
-type PlayResult struct {
- YouWon bool // True if the player receiving the result won the game.
-}
-
-// Player can receive challenges from other players.
-type Player interface {
- // Challenge is used by other players to challenge this player to a game. If
- // the challenge is accepted, the method returns nil.
- Challenge(Address string, ID GameID, Opts GameOptions) error
-}
-
-// ScoreKeeper receives the outcome of games from Judges.
-type ScoreKeeper interface {
- Record(Score ScoreCard) error
-}
-
-type ScoreCard struct {
- Opts GameOptions // The game options.
- Judge string // The name of the judge.
- Players []string // The name of the players.
- Rounds []Round // The outcome of each round.
- StartTimeNS int64 // The time at which the game started.
- EndTimeNS int64 // The time at which the game ended.
- Winner WinnerTag // Who won the game.
-}
diff --git a/examples/rockpaperscissors/service.vdl.go b/examples/rockpaperscissors/service.vdl.go
deleted file mode 100644
index 9bbc6de..0000000
--- a/examples/rockpaperscissors/service.vdl.go
+++ /dev/null
@@ -1,1267 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: service.vdl
-
-package rockpaperscissors
-
-import (
- // The non-user imports are prefixed with "_gen_" to prevent collisions.
- _gen_io "io"
- _gen_veyron2 "veyron2"
- _gen_context "veyron2/context"
- _gen_ipc "veyron2/ipc"
- _gen_naming "veyron2/naming"
- _gen_vdlutil "veyron2/vdl/vdlutil"
- _gen_wiretype "veyron2/wiretype"
-)
-
-// A GameID is used to uniquely identify a game within one Judge.
-type GameID struct {
- ID string
-}
-
-// GameOptions specifies the parameters of a game.
-type GameOptions struct {
- NumRounds int32 // The number of rounds that a player must win to win the game.
- GameType GameTypeTag // The type of game to play: Classic or LizardSpock.
-}
-
-type GameTypeTag byte
-
-type PlayerAction struct {
- Move string // The move that the player wants to make.
- Quit bool // Whether the player wants to quit the game.
-}
-
-type JudgeAction struct {
- PlayerNum int32 // The player's number.
- OpponentName string // The name of the opponent.
- MoveOptions []string // A list of allowed moves that the player must choose from. Not always present.
- RoundResult Round // The result of the previous round. Not always present.
- Score ScoreCard // The result of the game. Not always present.
-}
-
-// Round represents the state of a round.
-type Round struct {
- Moves [2]string // Each player's move.
- Comment string // A text comment from judge about the round.
- Winner WinnerTag // Who won the round.
- StartTimeNS int64 // The time at which the round started.
- EndTimeNS int64 // The time at which the round ended.
-}
-
-// WinnerTag is a type used to indicate whether a round or a game was a draw,
-// was won by player 1 or was won by player 2.
-type WinnerTag byte
-
-// PlayResult is the value returned by the Play method. It indicates the outcome of the game.
-type PlayResult struct {
- YouWon bool // True if the player receiving the result won the game.
-}
-
-type ScoreCard struct {
- Opts GameOptions // The game options.
- Judge string // The name of the judge.
- Players []string // The name of the players.
- Rounds []Round // The outcome of each round.
- StartTimeNS int64 // The time at which the game started.
- EndTimeNS int64 // The time at which the game ended.
- Winner WinnerTag // Who won the game.
-}
-
-const Classic = GameTypeTag(0) // Rock-Paper-Scissors
-
-const LizardSpock = GameTypeTag(1) // Rock-Paper-Scissors-Lizard-Spock
-
-const Draw = WinnerTag(0)
-
-const Player1 = WinnerTag(1)
-
-const Player2 = WinnerTag(2)
-
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
-const _ = _gen_wiretype.TypeIDInvalid
-
-// Judge is the interface the client binds and uses.
-// Judge_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type Judge_ExcludingUniversal interface {
- // CreateGame creates a new game with the given game options and returns a game
- // identifier that can be used by the players to join the game.
- CreateGame(ctx _gen_context.T, Opts GameOptions, opts ..._gen_ipc.CallOpt) (reply GameID, err error)
- // Play lets a player join an existing game and play.
- Play(ctx _gen_context.T, ID GameID, opts ..._gen_ipc.CallOpt) (reply JudgePlayCall, err error)
-}
-type Judge interface {
- _gen_ipc.UniversalServiceMethods
- Judge_ExcludingUniversal
-}
-
-// JudgeService is the interface the server implements.
-type JudgeService interface {
-
- // CreateGame creates a new game with the given game options and returns a game
- // identifier that can be used by the players to join the game.
- CreateGame(context _gen_ipc.ServerContext, Opts GameOptions) (reply GameID, err error)
- // Play lets a player join an existing game and play.
- Play(context _gen_ipc.ServerContext, ID GameID, stream JudgeServicePlayStream) (reply PlayResult, err error)
-}
-
-// JudgePlayCall is the interface for call object of the method
-// Play in the service interface Judge.
-type JudgePlayCall interface {
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() JudgeAction
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-
- // SendStream returns the send portion of the stream
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no
- // buffer space available. Calls to Send after having called Close
- // or Cancel will fail. Any blocked Send calls will be unblocked upon
- // calling Cancel.
- Send(item PlayerAction) error
-
- // Close indicates to the server that no more items will be sent;
- // server Recv calls will receive io.EOF after all sent items. This is
- // an optional call - it's used by streaming clients that need the
- // server to receive the io.EOF terminator before the client calls
- // Finish (for example, if the client needs to continue receiving items
- // from the server after having finished sending).
- // Calls to Close after having called Cancel will fail.
- // Like Send, Close blocks when there's no buffer space available.
- Close() error
- }
-
- // Finish performs the equivalent of SendStream().Close, then blocks until the server
- // is done, and returns the positional return values for call.
- // If Cancel has been called, Finish will return immediately; the output of
- // Finish could either be an error signalling cancelation, or the correct
- // positional return values from the server depending on the timing of the
- // call.
- //
- // Calling Finish is mandatory for releasing stream resources, unless Cancel
- // has been called or any of the other methods return an error.
- // Finish should be called at most once.
- Finish() (reply PlayResult, err error)
-
- // Cancel cancels the RPC, notifying the server to stop processing. It
- // is safe to call Cancel concurrently with any of the other stream methods.
- // Calling Cancel after Finish has returned is a no-op.
- Cancel()
-}
-
-type implJudgePlayStreamSender struct {
- clientCall _gen_ipc.Call
-}
-
-func (c *implJudgePlayStreamSender) Send(item PlayerAction) error {
- return c.clientCall.Send(item)
-}
-
-func (c *implJudgePlayStreamSender) Close() error {
- return c.clientCall.CloseSend()
-}
-
-type implJudgePlayStreamIterator struct {
- clientCall _gen_ipc.Call
- val JudgeAction
- err error
-}
-
-func (c *implJudgePlayStreamIterator) Advance() bool {
- c.val = JudgeAction{}
- c.err = c.clientCall.Recv(&c.val)
- return c.err == nil
-}
-
-func (c *implJudgePlayStreamIterator) Value() JudgeAction {
- return c.val
-}
-
-func (c *implJudgePlayStreamIterator) Err() error {
- if c.err == _gen_io.EOF {
- return nil
- }
- return c.err
-}
-
-// Implementation of the JudgePlayCall interface that is not exported.
-type implJudgePlayCall struct {
- clientCall _gen_ipc.Call
- writeStream implJudgePlayStreamSender
- readStream implJudgePlayStreamIterator
-}
-
-func (c *implJudgePlayCall) SendStream() interface {
- Send(item PlayerAction) error
- Close() error
-} {
- return &c.writeStream
-}
-
-func (c *implJudgePlayCall) RecvStream() interface {
- Advance() bool
- Value() JudgeAction
- Err() error
-} {
- return &c.readStream
-}
-
-func (c *implJudgePlayCall) Finish() (reply PlayResult, err error) {
- if ierr := c.clientCall.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (c *implJudgePlayCall) Cancel() {
- c.clientCall.Cancel()
-}
-
-type implJudgeServicePlayStreamSender struct {
- serverCall _gen_ipc.ServerCall
-}
-
-func (s *implJudgeServicePlayStreamSender) Send(item JudgeAction) error {
- return s.serverCall.Send(item)
-}
-
-type implJudgeServicePlayStreamIterator struct {
- serverCall _gen_ipc.ServerCall
- val PlayerAction
- err error
-}
-
-func (s *implJudgeServicePlayStreamIterator) Advance() bool {
- s.val = PlayerAction{}
- s.err = s.serverCall.Recv(&s.val)
- return s.err == nil
-}
-
-func (s *implJudgeServicePlayStreamIterator) Value() PlayerAction {
- return s.val
-}
-
-func (s *implJudgeServicePlayStreamIterator) Err() error {
- if s.err == _gen_io.EOF {
- return nil
- }
- return s.err
-}
-
-// JudgeServicePlayStream is the interface for streaming responses of the method
-// Play in the service interface Judge.
-type JudgeServicePlayStream interface {
- // SendStream returns the send portion of the stream.
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item JudgeAction) error
- }
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() PlayerAction
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-}
-
-// Implementation of the JudgeServicePlayStream interface that is not exported.
-type implJudgeServicePlayStream struct {
- writer implJudgeServicePlayStreamSender
- reader implJudgeServicePlayStreamIterator
-}
-
-func (s *implJudgeServicePlayStream) SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item JudgeAction) error
-} {
- return &s.writer
-}
-
-func (s *implJudgeServicePlayStream) RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. The client must call Cancel if it does
- // not iterate through all elements (i.e. until Advance
- // returns false). Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() PlayerAction
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
-} {
- return &s.reader
-}
-
-// BindJudge returns the client stub implementing the Judge
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindJudge(name string, opts ..._gen_ipc.BindOpt) (Judge, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubJudge{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerJudge creates a new server stub.
-//
-// It takes a regular server implementing the JudgeService
-// interface, and returns a new server stub.
-func NewServerJudge(server JudgeService) interface{} {
- return &ServerStubJudge{
- service: server,
- }
-}
-
-// clientStubJudge implements Judge.
-type clientStubJudge struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubJudge) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubJudge) CreateGame(ctx _gen_context.T, Opts GameOptions, opts ..._gen_ipc.CallOpt) (reply GameID, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "CreateGame", []interface{}{Opts}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubJudge) Play(ctx _gen_context.T, ID GameID, opts ..._gen_ipc.CallOpt) (reply JudgePlayCall, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Play", []interface{}{ID}, opts...); err != nil {
- return
- }
- reply = &implJudgePlayCall{clientCall: call, writeStream: implJudgePlayStreamSender{clientCall: call}, readStream: implJudgePlayStreamIterator{clientCall: call}}
- return
-}
-
-func (__gen_c *clientStubJudge) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubJudge) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubJudge) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubJudge wraps a server that implements
-// JudgeService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubJudge struct {
- service JudgeService
-}
-
-func (__gen_s *ServerStubJudge) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "CreateGame":
- return []interface{}{}, nil
- case "Play":
- return []interface{}{}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubJudge) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["CreateGame"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "Opts", Type: 66},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 67},
- {Name: "", Type: 68},
- },
- }
- result.Methods["Play"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "ID", Type: 67},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 69},
- {Name: "", Type: 68},
- },
- InStream: 70,
- OutStream: 76,
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron/examples/rockpaperscissors.GameTypeTag", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x24, Name: "NumRounds"},
- _gen_wiretype.FieldType{Type: 0x41, Name: "GameType"},
- },
- "veyron/examples/rockpaperscissors.GameOptions", []string(nil)},
- _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x3, Name: "ID"},
- },
- "veyron/examples/rockpaperscissors.GameID", []string(nil)},
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x2, Name: "YouWon"},
- },
- "veyron/examples/rockpaperscissors.PlayResult", []string(nil)},
- _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x3, Name: "Move"},
- _gen_wiretype.FieldType{Type: 0x2, Name: "Quit"},
- },
- "veyron/examples/rockpaperscissors.PlayerAction", []string(nil)},
- _gen_wiretype.ArrayType{Elem: 0x3, Len: 0x2, Name: "", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron/examples/rockpaperscissors.WinnerTag", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x47, Name: "Moves"},
- _gen_wiretype.FieldType{Type: 0x3, Name: "Comment"},
- _gen_wiretype.FieldType{Type: 0x48, Name: "Winner"},
- _gen_wiretype.FieldType{Type: 0x25, Name: "StartTimeNS"},
- _gen_wiretype.FieldType{Type: 0x25, Name: "EndTimeNS"},
- },
- "veyron/examples/rockpaperscissors.Round", []string(nil)},
- _gen_wiretype.SliceType{Elem: 0x49, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x42, Name: "Opts"},
- _gen_wiretype.FieldType{Type: 0x3, Name: "Judge"},
- _gen_wiretype.FieldType{Type: 0x3d, Name: "Players"},
- _gen_wiretype.FieldType{Type: 0x4a, Name: "Rounds"},
- _gen_wiretype.FieldType{Type: 0x25, Name: "StartTimeNS"},
- _gen_wiretype.FieldType{Type: 0x25, Name: "EndTimeNS"},
- _gen_wiretype.FieldType{Type: 0x48, Name: "Winner"},
- },
- "veyron/examples/rockpaperscissors.ScoreCard", []string(nil)},
- _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x24, Name: "PlayerNum"},
- _gen_wiretype.FieldType{Type: 0x3, Name: "OpponentName"},
- _gen_wiretype.FieldType{Type: 0x3d, Name: "MoveOptions"},
- _gen_wiretype.FieldType{Type: 0x49, Name: "RoundResult"},
- _gen_wiretype.FieldType{Type: 0x4b, Name: "Score"},
- },
- "veyron/examples/rockpaperscissors.JudgeAction", []string(nil)},
- }
-
- return result, nil
-}
-
-func (__gen_s *ServerStubJudge) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubJudge) CreateGame(call _gen_ipc.ServerCall, Opts GameOptions) (reply GameID, err error) {
- reply, err = __gen_s.service.CreateGame(call, Opts)
- return
-}
-
-func (__gen_s *ServerStubJudge) Play(call _gen_ipc.ServerCall, ID GameID) (reply PlayResult, err error) {
- stream := &implJudgeServicePlayStream{reader: implJudgeServicePlayStreamIterator{serverCall: call}, writer: implJudgeServicePlayStreamSender{serverCall: call}}
- reply, err = __gen_s.service.Play(call, ID, stream)
- return
-}
-
-// Player can receive challenges from other players.
-// Player is the interface the client binds and uses.
-// Player_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type Player_ExcludingUniversal interface {
- // Challenge is used by other players to challenge this player to a game. If
- // the challenge is accepted, the method returns nil.
- Challenge(ctx _gen_context.T, Address string, ID GameID, Opts GameOptions, opts ..._gen_ipc.CallOpt) (err error)
-}
-type Player interface {
- _gen_ipc.UniversalServiceMethods
- Player_ExcludingUniversal
-}
-
-// PlayerService is the interface the server implements.
-type PlayerService interface {
-
- // Challenge is used by other players to challenge this player to a game. If
- // the challenge is accepted, the method returns nil.
- Challenge(context _gen_ipc.ServerContext, Address string, ID GameID, Opts GameOptions) (err error)
-}
-
-// BindPlayer returns the client stub implementing the Player
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindPlayer(name string, opts ..._gen_ipc.BindOpt) (Player, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubPlayer{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerPlayer creates a new server stub.
-//
-// It takes a regular server implementing the PlayerService
-// interface, and returns a new server stub.
-func NewServerPlayer(server PlayerService) interface{} {
- return &ServerStubPlayer{
- service: server,
- }
-}
-
-// clientStubPlayer implements Player.
-type clientStubPlayer struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubPlayer) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubPlayer) Challenge(ctx _gen_context.T, Address string, ID GameID, Opts GameOptions, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Challenge", []interface{}{Address, ID, Opts}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubPlayer) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubPlayer) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubPlayer) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubPlayer wraps a server that implements
-// PlayerService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubPlayer struct {
- service PlayerService
-}
-
-func (__gen_s *ServerStubPlayer) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Challenge":
- return []interface{}{}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubPlayer) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Challenge"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "Address", Type: 3},
- {Name: "ID", Type: 65},
- {Name: "Opts", Type: 67},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 68},
- },
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x3, Name: "ID"},
- },
- "veyron/examples/rockpaperscissors.GameID", []string(nil)},
- _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron/examples/rockpaperscissors.GameTypeTag", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x24, Name: "NumRounds"},
- _gen_wiretype.FieldType{Type: 0x42, Name: "GameType"},
- },
- "veyron/examples/rockpaperscissors.GameOptions", []string(nil)},
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
-
- return result, nil
-}
-
-func (__gen_s *ServerStubPlayer) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubPlayer) Challenge(call _gen_ipc.ServerCall, Address string, ID GameID, Opts GameOptions) (err error) {
- err = __gen_s.service.Challenge(call, Address, ID, Opts)
- return
-}
-
-// ScoreKeeper receives the outcome of games from Judges.
-// ScoreKeeper is the interface the client binds and uses.
-// ScoreKeeper_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type ScoreKeeper_ExcludingUniversal interface {
- Record(ctx _gen_context.T, Score ScoreCard, opts ..._gen_ipc.CallOpt) (err error)
-}
-type ScoreKeeper interface {
- _gen_ipc.UniversalServiceMethods
- ScoreKeeper_ExcludingUniversal
-}
-
-// ScoreKeeperService is the interface the server implements.
-type ScoreKeeperService interface {
- Record(context _gen_ipc.ServerContext, Score ScoreCard) (err error)
-}
-
-// BindScoreKeeper returns the client stub implementing the ScoreKeeper
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindScoreKeeper(name string, opts ..._gen_ipc.BindOpt) (ScoreKeeper, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubScoreKeeper{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerScoreKeeper creates a new server stub.
-//
-// It takes a regular server implementing the ScoreKeeperService
-// interface, and returns a new server stub.
-func NewServerScoreKeeper(server ScoreKeeperService) interface{} {
- return &ServerStubScoreKeeper{
- service: server,
- }
-}
-
-// clientStubScoreKeeper implements ScoreKeeper.
-type clientStubScoreKeeper struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubScoreKeeper) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubScoreKeeper) Record(ctx _gen_context.T, Score ScoreCard, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Record", []interface{}{Score}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubScoreKeeper) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubScoreKeeper) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubScoreKeeper) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubScoreKeeper wraps a server that implements
-// ScoreKeeperService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubScoreKeeper struct {
- service ScoreKeeperService
-}
-
-func (__gen_s *ServerStubScoreKeeper) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Record":
- return []interface{}{}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubScoreKeeper) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Record"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "Score", Type: 71},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 72},
- },
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron/examples/rockpaperscissors.GameTypeTag", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x24, Name: "NumRounds"},
- _gen_wiretype.FieldType{Type: 0x41, Name: "GameType"},
- },
- "veyron/examples/rockpaperscissors.GameOptions", []string(nil)},
- _gen_wiretype.ArrayType{Elem: 0x3, Len: 0x2, Name: "", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron/examples/rockpaperscissors.WinnerTag", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x43, Name: "Moves"},
- _gen_wiretype.FieldType{Type: 0x3, Name: "Comment"},
- _gen_wiretype.FieldType{Type: 0x44, Name: "Winner"},
- _gen_wiretype.FieldType{Type: 0x25, Name: "StartTimeNS"},
- _gen_wiretype.FieldType{Type: 0x25, Name: "EndTimeNS"},
- },
- "veyron/examples/rockpaperscissors.Round", []string(nil)},
- _gen_wiretype.SliceType{Elem: 0x45, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x42, Name: "Opts"},
- _gen_wiretype.FieldType{Type: 0x3, Name: "Judge"},
- _gen_wiretype.FieldType{Type: 0x3d, Name: "Players"},
- _gen_wiretype.FieldType{Type: 0x46, Name: "Rounds"},
- _gen_wiretype.FieldType{Type: 0x25, Name: "StartTimeNS"},
- _gen_wiretype.FieldType{Type: 0x25, Name: "EndTimeNS"},
- _gen_wiretype.FieldType{Type: 0x44, Name: "Winner"},
- },
- "veyron/examples/rockpaperscissors.ScoreCard", []string(nil)},
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
-
- return result, nil
-}
-
-func (__gen_s *ServerStubScoreKeeper) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubScoreKeeper) Record(call _gen_ipc.ServerCall, Score ScoreCard) (err error) {
- err = __gen_s.service.Record(call, Score)
- return
-}
-
-// RockPaperScissors is the interface the client binds and uses.
-// RockPaperScissors_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type RockPaperScissors_ExcludingUniversal interface {
- Judge_ExcludingUniversal
- // Player can receive challenges from other players.
- Player_ExcludingUniversal
- // ScoreKeeper receives the outcome of games from Judges.
- ScoreKeeper_ExcludingUniversal
-}
-type RockPaperScissors interface {
- _gen_ipc.UniversalServiceMethods
- RockPaperScissors_ExcludingUniversal
-}
-
-// RockPaperScissorsService is the interface the server implements.
-type RockPaperScissorsService interface {
- JudgeService
- // Player can receive challenges from other players.
- PlayerService
- // ScoreKeeper receives the outcome of games from Judges.
- ScoreKeeperService
-}
-
-// BindRockPaperScissors returns the client stub implementing the RockPaperScissors
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindRockPaperScissors(name string, opts ..._gen_ipc.BindOpt) (RockPaperScissors, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubRockPaperScissors{defaultClient: client, name: name}
- stub.Judge_ExcludingUniversal, _ = BindJudge(name, client)
- stub.Player_ExcludingUniversal, _ = BindPlayer(name, client)
- stub.ScoreKeeper_ExcludingUniversal, _ = BindScoreKeeper(name, client)
-
- return stub, nil
-}
-
-// NewServerRockPaperScissors creates a new server stub.
-//
-// It takes a regular server implementing the RockPaperScissorsService
-// interface, and returns a new server stub.
-func NewServerRockPaperScissors(server RockPaperScissorsService) interface{} {
- return &ServerStubRockPaperScissors{
- ServerStubJudge: *NewServerJudge(server).(*ServerStubJudge),
- ServerStubPlayer: *NewServerPlayer(server).(*ServerStubPlayer),
- ServerStubScoreKeeper: *NewServerScoreKeeper(server).(*ServerStubScoreKeeper),
- service: server,
- }
-}
-
-// clientStubRockPaperScissors implements RockPaperScissors.
-type clientStubRockPaperScissors struct {
- Judge_ExcludingUniversal
- Player_ExcludingUniversal
- ScoreKeeper_ExcludingUniversal
-
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubRockPaperScissors) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubRockPaperScissors) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubRockPaperScissors) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubRockPaperScissors) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubRockPaperScissors wraps a server that implements
-// RockPaperScissorsService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubRockPaperScissors struct {
- ServerStubJudge
- ServerStubPlayer
- ServerStubScoreKeeper
-
- service RockPaperScissorsService
-}
-
-func (__gen_s *ServerStubRockPaperScissors) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- if resp, err := __gen_s.ServerStubJudge.GetMethodTags(call, method); resp != nil || err != nil {
- return resp, err
- }
- if resp, err := __gen_s.ServerStubPlayer.GetMethodTags(call, method); resp != nil || err != nil {
- return resp, err
- }
- if resp, err := __gen_s.ServerStubScoreKeeper.GetMethodTags(call, method); resp != nil || err != nil {
- return resp, err
- }
- return nil, nil
-}
-
-func (__gen_s *ServerStubRockPaperScissors) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
-
- result.TypeDefs = []_gen_vdlutil.Any{}
- var ss _gen_ipc.ServiceSignature
- var firstAdded int
- ss, _ = __gen_s.ServerStubJudge.Signature(call)
- firstAdded = len(result.TypeDefs)
- for k, v := range ss.Methods {
- for i, _ := range v.InArgs {
- if v.InArgs[i].Type >= _gen_wiretype.TypeIDFirst {
- v.InArgs[i].Type += _gen_wiretype.TypeID(firstAdded)
- }
- }
- for i, _ := range v.OutArgs {
- if v.OutArgs[i].Type >= _gen_wiretype.TypeIDFirst {
- v.OutArgs[i].Type += _gen_wiretype.TypeID(firstAdded)
- }
- }
- if v.InStream >= _gen_wiretype.TypeIDFirst {
- v.InStream += _gen_wiretype.TypeID(firstAdded)
- }
- if v.OutStream >= _gen_wiretype.TypeIDFirst {
- v.OutStream += _gen_wiretype.TypeID(firstAdded)
- }
- result.Methods[k] = v
- }
- //TODO(bprosnitz) combine type definitions from embeded interfaces in a way that doesn't cause duplication.
- for _, d := range ss.TypeDefs {
- switch wt := d.(type) {
- case _gen_wiretype.SliceType:
- if wt.Elem >= _gen_wiretype.TypeIDFirst {
- wt.Elem += _gen_wiretype.TypeID(firstAdded)
- }
- d = wt
- case _gen_wiretype.ArrayType:
- if wt.Elem >= _gen_wiretype.TypeIDFirst {
- wt.Elem += _gen_wiretype.TypeID(firstAdded)
- }
- d = wt
- case _gen_wiretype.MapType:
- if wt.Key >= _gen_wiretype.TypeIDFirst {
- wt.Key += _gen_wiretype.TypeID(firstAdded)
- }
- if wt.Elem >= _gen_wiretype.TypeIDFirst {
- wt.Elem += _gen_wiretype.TypeID(firstAdded)
- }
- d = wt
- case _gen_wiretype.StructType:
- for i, fld := range wt.Fields {
- if fld.Type >= _gen_wiretype.TypeIDFirst {
- wt.Fields[i].Type += _gen_wiretype.TypeID(firstAdded)
- }
- }
- d = wt
- // NOTE: other types are missing, but we are upgrading anyways.
- }
- result.TypeDefs = append(result.TypeDefs, d)
- }
- ss, _ = __gen_s.ServerStubPlayer.Signature(call)
- firstAdded = len(result.TypeDefs)
- for k, v := range ss.Methods {
- for i, _ := range v.InArgs {
- if v.InArgs[i].Type >= _gen_wiretype.TypeIDFirst {
- v.InArgs[i].Type += _gen_wiretype.TypeID(firstAdded)
- }
- }
- for i, _ := range v.OutArgs {
- if v.OutArgs[i].Type >= _gen_wiretype.TypeIDFirst {
- v.OutArgs[i].Type += _gen_wiretype.TypeID(firstAdded)
- }
- }
- if v.InStream >= _gen_wiretype.TypeIDFirst {
- v.InStream += _gen_wiretype.TypeID(firstAdded)
- }
- if v.OutStream >= _gen_wiretype.TypeIDFirst {
- v.OutStream += _gen_wiretype.TypeID(firstAdded)
- }
- result.Methods[k] = v
- }
- //TODO(bprosnitz) combine type definitions from embeded interfaces in a way that doesn't cause duplication.
- for _, d := range ss.TypeDefs {
- switch wt := d.(type) {
- case _gen_wiretype.SliceType:
- if wt.Elem >= _gen_wiretype.TypeIDFirst {
- wt.Elem += _gen_wiretype.TypeID(firstAdded)
- }
- d = wt
- case _gen_wiretype.ArrayType:
- if wt.Elem >= _gen_wiretype.TypeIDFirst {
- wt.Elem += _gen_wiretype.TypeID(firstAdded)
- }
- d = wt
- case _gen_wiretype.MapType:
- if wt.Key >= _gen_wiretype.TypeIDFirst {
- wt.Key += _gen_wiretype.TypeID(firstAdded)
- }
- if wt.Elem >= _gen_wiretype.TypeIDFirst {
- wt.Elem += _gen_wiretype.TypeID(firstAdded)
- }
- d = wt
- case _gen_wiretype.StructType:
- for i, fld := range wt.Fields {
- if fld.Type >= _gen_wiretype.TypeIDFirst {
- wt.Fields[i].Type += _gen_wiretype.TypeID(firstAdded)
- }
- }
- d = wt
- // NOTE: other types are missing, but we are upgrading anyways.
- }
- result.TypeDefs = append(result.TypeDefs, d)
- }
- ss, _ = __gen_s.ServerStubScoreKeeper.Signature(call)
- firstAdded = len(result.TypeDefs)
- for k, v := range ss.Methods {
- for i, _ := range v.InArgs {
- if v.InArgs[i].Type >= _gen_wiretype.TypeIDFirst {
- v.InArgs[i].Type += _gen_wiretype.TypeID(firstAdded)
- }
- }
- for i, _ := range v.OutArgs {
- if v.OutArgs[i].Type >= _gen_wiretype.TypeIDFirst {
- v.OutArgs[i].Type += _gen_wiretype.TypeID(firstAdded)
- }
- }
- if v.InStream >= _gen_wiretype.TypeIDFirst {
- v.InStream += _gen_wiretype.TypeID(firstAdded)
- }
- if v.OutStream >= _gen_wiretype.TypeIDFirst {
- v.OutStream += _gen_wiretype.TypeID(firstAdded)
- }
- result.Methods[k] = v
- }
- //TODO(bprosnitz) combine type definitions from embeded interfaces in a way that doesn't cause duplication.
- for _, d := range ss.TypeDefs {
- switch wt := d.(type) {
- case _gen_wiretype.SliceType:
- if wt.Elem >= _gen_wiretype.TypeIDFirst {
- wt.Elem += _gen_wiretype.TypeID(firstAdded)
- }
- d = wt
- case _gen_wiretype.ArrayType:
- if wt.Elem >= _gen_wiretype.TypeIDFirst {
- wt.Elem += _gen_wiretype.TypeID(firstAdded)
- }
- d = wt
- case _gen_wiretype.MapType:
- if wt.Key >= _gen_wiretype.TypeIDFirst {
- wt.Key += _gen_wiretype.TypeID(firstAdded)
- }
- if wt.Elem >= _gen_wiretype.TypeIDFirst {
- wt.Elem += _gen_wiretype.TypeID(firstAdded)
- }
- d = wt
- case _gen_wiretype.StructType:
- for i, fld := range wt.Fields {
- if fld.Type >= _gen_wiretype.TypeIDFirst {
- wt.Fields[i].Type += _gen_wiretype.TypeID(firstAdded)
- }
- }
- d = wt
- // NOTE: other types are missing, but we are upgrading anyways.
- }
- result.TypeDefs = append(result.TypeDefs, d)
- }
-
- return result, nil
-}
-
-func (__gen_s *ServerStubRockPaperScissors) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
diff --git a/examples/runtime/complex_server.go b/examples/runtime/complex_server.go
deleted file mode 100644
index 66a0122..0000000
--- a/examples/runtime/complex_server.go
+++ /dev/null
@@ -1,146 +0,0 @@
-package runtime
-
-import (
- "fmt"
- "os"
- "os/signal"
- "sync"
- "syscall"
-
- "veyron2/rt"
-)
-
-// complexServerProgram demonstrates the recommended way to write a more complex
-// server application (with several servers, a mix of interruptible and blocking
-// cleanup, and parallel and sequential cleanup execution). For a more typical
-// server, see simpleServerProgram.
-func complexServerProgram() {
- // Initialize the runtime. This is boilerplate.
- r := rt.Init()
- // r.Cleanup is optional, but it's a good idea to clean up, especially
- // since it takes care of flushing the logs before exiting.
- defer r.Cleanup()
-
- // Create a couple servers, and start serving.
- server1 := makeServer()
- server2 := makeServer()
-
- // This is how to wait for a shutdown. In this example, a shutdown
- // comes from a signal or a stop command.
- var done sync.WaitGroup
- done.Add(1)
-
- // This is how to configure signal handling to allow clean shutdown.
- sigChan := make(chan os.Signal, 2)
- signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)
-
- // This is how to configure handling of stop commands to allow clean
- // shutdown.
- stopChan := make(chan string, 2)
- r.WaitForStop(stopChan)
-
- // Blocking is used to prevent the process from exiting upon receiving a
- // second signal or stop command while critical cleanup code is
- // executing.
- var blocking sync.WaitGroup
- blockingCh := make(chan struct{})
-
- // This is how to wait for a signal or stop command and initiate the
- // clean shutdown steps.
- go func() {
- // First signal received.
- select {
- case sig := <-sigChan:
- // If the developer wants to take different actions
- // depending on the type of signal, they can do it here.
- fmt.Println("Received signal", sig)
- case stop := <-stopChan:
- fmt.Println("Stop", stop)
- }
- // This commences the cleanup stage.
- done.Done()
- // Wait for a second signal or stop command, and force an exit,
- // but only once all blocking cleanup code (if any) has
- // completed.
- select {
- case <-sigChan:
- case <-stopChan:
- }
- <-blockingCh
- os.Exit(1)
- }()
-
- // This communicates to the parent test driver process in our unit test
- // that this server is ready and waiting on signals or stop commands.
- // It's purely an artifact of our test setup.
- fmt.Println("Ready")
-
- // Wait for shutdown.
- done.Wait()
-
- // Stop the servers. In this example we stop them in goroutines to
- // parallelize the wait, but if there was a dependency between the
- // servers, the developer can simply stop them sequentially.
- var waitServerStop sync.WaitGroup
- waitServerStop.Add(2)
- go func() {
- server1.Stop()
- waitServerStop.Done()
- }()
- go func() {
- server2.Stop()
- waitServerStop.Done()
- }()
- waitServerStop.Wait()
-
- // This is where all cleanup code should go. By placing it at the end,
- // we make its purpose and order of execution clear.
-
- // This is an example of how to mix parallel and sequential cleanup
- // steps. Most real-world servers will likely be simpler, with either
- // just sequential or just parallel cleanup stages.
-
- // parallelCleanup is used to wait for all goroutines executing cleanup
- // code in parallel to finish.
- var parallelCleanup sync.WaitGroup
-
- // Simulate four parallel cleanup steps, two blocking and two
- // interruptible.
- parallelCleanup.Add(1)
- blocking.Add(1)
- go func() {
- fmt.Println("Parallel blocking cleanup1")
- blocking.Done()
- parallelCleanup.Done()
- }()
-
- parallelCleanup.Add(1)
- blocking.Add(1)
- go func() {
- fmt.Println("Parallel blocking cleanup2")
- blocking.Done()
- parallelCleanup.Done()
- }()
-
- parallelCleanup.Add(1)
- go func() {
- fmt.Println("Parallel interruptible cleanup1")
- parallelCleanup.Done()
- }()
-
- parallelCleanup.Add(1)
- go func() {
- fmt.Println("Parallel interruptible cleanup2")
- parallelCleanup.Done()
- }()
-
- // Simulate two sequential cleanup steps, one blocking and one
- // interruptible.
- fmt.Println("Sequential blocking cleanup")
- blocking.Wait()
- close(blockingCh)
-
- fmt.Println("Sequential interruptible cleanup")
-
- parallelCleanup.Wait()
-}
diff --git a/examples/runtime/doc.go b/examples/runtime/doc.go
deleted file mode 100644
index 4a334b3..0000000
--- a/examples/runtime/doc.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// Package runtime contains example Veyron programs to demonstrate correct,
-// idiomatic usage of the Veyron runtime APIs.
-package runtime
-
-// TODO(caprita): Using these as a basis, develop a suite of codelab examples
-// that introduce developers to writing servers (stateful and stateless),
-// setting up their shutdown, etc.
diff --git a/examples/runtime/runtime_test.go b/examples/runtime/runtime_test.go
deleted file mode 100644
index ebb19ba..0000000
--- a/examples/runtime/runtime_test.go
+++ /dev/null
@@ -1,203 +0,0 @@
-package runtime
-
-import (
- "fmt"
- "syscall"
- "testing"
- "time"
-
- "veyron/lib/signals"
- _ "veyron/lib/testutil"
- "veyron/lib/testutil/blackbox"
-
- "veyron2"
-)
-
-// TestHelperProcess is boilerplate for the blackbox setup.
-func TestHelperProcess(t *testing.T) {
- blackbox.HelperProcess(t)
-}
-
-func init() {
- blackbox.CommandTable["simpleServerProgram"] = func([]string) {
- // This is part of the test setup -- we need a way to accept
- // commands from the parent process to simulate Stop and
- // RemoteStop commands that would normally be issued from
- // application code.
- defer remoteCmdLoop()()
- simpleServerProgram()
- }
-}
-
-// TestSimpleServerSignal verifies that sending a signal to the simple server
-// causes it to exit cleanly.
-func TestSimpleServerSignal(t *testing.T) {
- c := blackbox.HelperCommand(t, "simpleServerProgram")
- defer c.Cleanup()
- c.Cmd.Start()
- c.Expect("Ready")
- syscall.Kill(c.Cmd.Process.Pid, syscall.SIGINT)
- c.Expect("Received signal interrupt")
- c.Expect("Interruptible cleanup")
- c.Expect("Deferred cleanup")
- c.WriteLine("close")
- c.ExpectEOFAndWait()
-}
-
-// TestSimpleServerLocalStop verifies that sending a local stop command to the
-// simple server causes it to exit cleanly.
-func TestSimpleServerLocalStop(t *testing.T) {
- c := blackbox.HelperCommand(t, "simpleServerProgram")
- defer c.Cleanup()
- c.Cmd.Start()
- c.Expect("Ready")
- c.WriteLine("stop")
- c.Expect(fmt.Sprintf("Received signal %s", veyron2.LocalStop))
- c.Expect("Interruptible cleanup")
- c.Expect("Deferred cleanup")
- c.WriteLine("close")
- c.ExpectEOFAndWait()
-}
-
-// TestSimpleServerDoubleSignal verifies that sending a succession of two
-// signals to the simple server causes it to initiate the cleanup sequence on
-// the first signal and then exit immediately on the second signal.
-func TestSimpleServerDoubleSignal(t *testing.T) {
- c := blackbox.HelperCommand(t, "simpleServerProgram")
- defer c.Cleanup()
- c.Cmd.Start()
- c.Expect("Ready")
- syscall.Kill(c.Cmd.Process.Pid, syscall.SIGINT)
- c.Expect("Received signal interrupt")
- syscall.Kill(c.Cmd.Process.Pid, syscall.SIGINT)
- c.WaitForEOF(time.Second)
- c.ExpectEOFAndWaitForExitCode(fmt.Errorf("exit status %d", signals.DoubleStopExitCode))
-}
-
-// TestSimpleServerLocalForceStop verifies that sending a local ForceStop
-// command to the simple server causes it to exit immediately.
-func TestSimpleServerLocalForceStop(t *testing.T) {
- c := blackbox.HelperCommand(t, "simpleServerProgram")
- defer c.Cleanup()
- c.Cmd.Start()
- c.Expect("Ready")
- c.WriteLine("forcestop")
- c.Expect("straight exit")
- c.ExpectEOFAndWaitForExitCode(fmt.Errorf("exit status %d", veyron2.ForceStopExitCode))
-}
-
-// TestSimpleServerKill demonstrates that a SIGKILL still forces the server
-// to exit regardless of our signal handling.
-func TestSimpleServerKill(t *testing.T) {
- c := blackbox.HelperCommand(t, "simpleServerProgram")
- defer c.Cleanup()
- c.Cmd.Start()
- c.Expect("Ready")
- syscall.Kill(c.Cmd.Process.Pid, syscall.SIGKILL)
- c.ExpectEOFAndWaitForExitCode(fmt.Errorf("signal: killed"))
-}
-
-func init() {
- blackbox.CommandTable["complexServerProgram"] = func([]string) {
- // This is part of the test setup -- we need a way to accept
- // commands from the parent process to simulate Stop and
- // RemoteStop commands that would normally be issued from
- // application code.
- defer remoteCmdLoop()()
- complexServerProgram()
- }
-}
-
-// TestComplexServerSignal verifies that sending a signal to the complex server
-// initiates the cleanup sequence in that server (we observe the printouts
-// corresponding to all the simulated sequential/parallel and
-// blocking/interruptible shutdown steps), and then exits cleanly.
-func TestComplexServerSignal(t *testing.T) {
- c := blackbox.HelperCommand(t, "complexServerProgram")
- defer c.Cleanup()
- c.Cmd.Start()
- c.Expect("Ready")
- syscall.Kill(c.Cmd.Process.Pid, syscall.SIGINT)
- c.Expect("Received signal interrupt")
- c.ExpectSet([]string{
- "Sequential blocking cleanup",
- "Sequential interruptible cleanup",
- "Parallel blocking cleanup1",
- "Parallel blocking cleanup2",
- "Parallel interruptible cleanup1",
- "Parallel interruptible cleanup2",
- })
- c.WriteLine("close")
- c.ExpectEOFAndWait()
-}
-
-// TestComplexServerLocalStop verifies that sending a local stop command to the
-// complex server initiates the cleanup sequence in that server (we observe the
-// printouts corresponding to all the simulated sequential/parallel and
-// blocking/interruptible shutdown steps), and then exits cleanly.
-func TestComplexServerLocalStop(t *testing.T) {
- c := blackbox.HelperCommand(t, "complexServerProgram")
- defer c.Cleanup()
- c.Cmd.Start()
- c.Expect("Ready")
- c.WriteLine("stop")
- c.Expect(fmt.Sprintf("Stop %s", veyron2.LocalStop))
- c.ExpectSet([]string{
- "Sequential blocking cleanup",
- "Sequential interruptible cleanup",
- "Parallel blocking cleanup1",
- "Parallel blocking cleanup2",
- "Parallel interruptible cleanup1",
- "Parallel interruptible cleanup2",
- })
- c.WriteLine("close")
- c.ExpectEOFAndWait()
-}
-
-// TestComplexServerDoubleSignal verifies that sending a succession of two
-// signals to the complex server has the expected effect: the first signal
-// initiates the cleanup steps and the second signal kills the process, but only
-// after the blocking shutdown steps were allowed to complete (as observed by
-// the corresponding printouts from the server). Note that we have no
-// expectations on whether or not the interruptible shutdown steps execute.
-func TestComplexServerDoubleSignal(t *testing.T) {
- c := blackbox.HelperCommand(t, "complexServerProgram")
- defer c.Cleanup()
- c.Cmd.Start()
- c.Expect("Ready")
- syscall.Kill(c.Cmd.Process.Pid, syscall.SIGINT)
- c.Expect("Received signal interrupt")
- syscall.Kill(c.Cmd.Process.Pid, syscall.SIGINT)
- c.ExpectSetEventually([]string{
- "Sequential blocking cleanup",
- "Parallel blocking cleanup1",
- "Parallel blocking cleanup2",
- }, time.Second)
- c.WaitForEOF(time.Second)
- c.ExpectEOFAndWaitForExitCode(fmt.Errorf("exit status %d", signals.DoubleStopExitCode))
-}
-
-// TestComplexServerLocalForceStop verifies that sending a local ForceStop
-// command to the complex server forces it to exit immediately.
-func TestComplexServerLocalForceStop(t *testing.T) {
- c := blackbox.HelperCommand(t, "complexServerProgram")
- defer c.Cleanup()
- c.Cmd.Start()
- c.Expect("Ready")
- c.WriteLine("forcestop")
- c.Expect("straight exit")
- c.ExpectEOFAndWaitForExitCode(fmt.Errorf("exit status %d", veyron2.ForceStopExitCode))
-}
-
-// TestComplexServerKill demonstrates that a SIGKILL still forces the server to
-// exit regardless of our signal handling.
-func TestComplexServerKill(t *testing.T) {
- c := blackbox.HelperCommand(t, "complexServerProgram")
- defer c.Cleanup()
- c.Cmd.Start()
- c.Expect("Ready")
- syscall.Kill(c.Cmd.Process.Pid, syscall.SIGKILL)
- c.ExpectEOFAndWaitForExitCode(fmt.Errorf("signal: killed"))
-}
-
-// TODO(caprita): Also demonstrate an example client application.
diff --git a/examples/runtime/simple_server.go b/examples/runtime/simple_server.go
deleted file mode 100644
index b459d80..0000000
--- a/examples/runtime/simple_server.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package runtime
-
-import (
- "fmt"
-
- "veyron/lib/signals"
-
- "veyron2/rt"
-)
-
-// simpleServerProgram demonstrates the recommended way to write a typical
-// simple server application (with one server and a clean shutdown triggered by
-// a signal or a stop command). For an example of something more involved, see
-// complexServerProgram.
-func simpleServerProgram() {
- // Initialize the runtime. This is boilerplate.
- r := rt.Init()
-
- // r.Cleanup is optional, but it's a good idea to clean up, especially
- // since it takes care of flushing the logs before exiting.
- //
- // We use defer to ensure this is the last thing in the program (to
- // avoid shutting down the runtime while it may still be in use), and to
- // allow it to execute even if a panic occurs down the road.
- defer r.Cleanup()
-
- // Create a server, and start serving.
- server := makeServer()
-
- // This is how to wait for a shutdown. In this example, a shutdown
- // comes from a signal or a stop command.
- //
- // Note, if the developer wants to exit immediately upon receiving a
- // signal or stop command, they can skip this, in which case the default
- // behavior is for the process to exit.
- waiter := signals.ShutdownOnSignals()
-
- // This communicates to the parent test driver process in our unit test
- // that this server is ready and waiting on signals or stop commands.
- // It's purely an artifact of our test setup.
- fmt.Println("Ready")
-
- // Use defer for anything that should still execute even if a panic
- // occurs.
- defer fmt.Println("Deferred cleanup")
-
- // Wait for shutdown.
- sig := <-waiter
- // The developer could take different actions depending on the type of
- // signal.
- fmt.Println("Received signal", sig)
-
- // Cleanup code starts here. Alternatively, these steps could be
- // invoked through defer, but we list them here to make the order of
- // operations obvious.
-
- // Stop the server.
- server.Stop()
-
- // Note, this will not execute in cases of forced shutdown
- // (e.g. SIGSTOP), when the process calls os.Exit (e.g. via log.Fatal),
- // or when a panic occurs.
- fmt.Println("Interruptible cleanup")
-}
diff --git a/examples/runtime/utils.go b/examples/runtime/utils.go
deleted file mode 100644
index edd15a7..0000000
--- a/examples/runtime/utils.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package runtime
-
-import (
- "fmt"
-
- "veyron2/ipc"
- "veyron2/rt"
- "veyron2/security"
- "veyron2/vlog"
-
- _ "veyron/lib/testutil"
- "veyron/lib/testutil/blackbox"
-)
-
-// dispatcher is a simple no-op dispatcher we use for setting up example
-// servers.
-type dispatcher struct{}
-
-func (dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
- return nil, nil, nil
-}
-
-// makeServer sets up a simple dummy server.
-func makeServer() ipc.Server {
- server, err := rt.R().NewServer()
- if err != nil {
- vlog.Fatalf("r.NewServer error: %s", err)
- }
- if _, err := server.Listen("tcp", "127.0.0.1:0"); err != nil {
- vlog.Fatalf("server.Listen error: %s", err)
- }
- if err := server.Serve("", new(dispatcher)); err != nil {
- vlog.Fatalf("server.Serve error: %s", err)
- }
- return server
-}
-
-// remoteCmdLoop listens on stdin and interprets commands sent over stdin (from
-// the parent process).
-func remoteCmdLoop() func() {
- done := make(chan struct{})
- go func() {
- defer close(done)
- for {
- switch blackbox.ReadLineFromStdin() {
- case "stop":
- rt.R().Stop()
- case "forcestop":
- fmt.Println("straight exit")
- rt.R().ForceStop()
- case "close":
- return
- }
- }
- }()
- return func() { <-done }
-}
diff --git a/examples/stfortune/schema/init.go b/examples/stfortune/schema/init.go
deleted file mode 100644
index 07af878..0000000
--- a/examples/stfortune/schema/init.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package schema
-
-import (
- "veyron2/vom"
-)
-
-func init() {
- vom.Register(&FortuneData{})
- vom.Register(&User{})
-}
diff --git a/examples/stfortune/schema/schema.vdl b/examples/stfortune/schema/schema.vdl
deleted file mode 100644
index f23b0fc..0000000
--- a/examples/stfortune/schema/schema.vdl
+++ /dev/null
@@ -1,16 +0,0 @@
-package schema
-
-import (
- "veyron.io/store/veyron2/storage"
-)
-
-// User contains the information corresponding to a particular UserName in the store.
-type User struct {
- Name string
-}
-
-// FortuneData contains the information regarding a fortune.
-type FortuneData struct {
- Fortune string
- UserName storage.ID
-}
diff --git a/examples/stfortune/schema/schema.vdl.go b/examples/stfortune/schema/schema.vdl.go
deleted file mode 100644
index 09cef86..0000000
--- a/examples/stfortune/schema/schema.vdl.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: schema.vdl
-
-package schema
-
-import (
- "veyron.io/store/veyron2/storage"
-)
-
-// User contains the information corresponding to a particular UserName in the store.
-type User struct {
- Name string
-}
-
-// FortuneData contains the information regarding a fortune.
-type FortuneData struct {
- Fortune string
- UserName storage.ID
-}
diff --git a/examples/stfortune/stfortune/main.go b/examples/stfortune/stfortune/main.go
deleted file mode 100644
index 18e193c..0000000
--- a/examples/stfortune/stfortune/main.go
+++ /dev/null
@@ -1,326 +0,0 @@
-// TODO(kash): Rewrite this to use the new dir/object store api.
-// +build ignore
-
-// Binary stfortune is a simple client of Veyron Store. See
-// http://go/veyron:codelab-store for a thorough explanation.
-package main
-
-import (
- "crypto/md5"
- "encoding/hex"
- "flag"
- "fmt"
- "io"
- "log"
- "math/rand"
- "os"
- "strings"
- "time"
- "veyron.io/store/veyron2/query"
-
- "veyron/examples/stfortune/schema"
-
- "veyron2/context"
- "veyron2/naming"
- "veyron2/rt"
- "veyron2/services/watch/types"
- "veyron.io/store/veyron2/storage"
- "veyron.io/store/veyron2/storage/vstore"
- "veyron2/vom"
-)
-
-func fortunePath(name string) string {
- return naming.Join(appPath, "fortunes", name)
-}
-
-func userPath(name string) string {
- return naming.Join(appPath, "usernames", name)
-}
-
-// Hashes a string.
-func getMD5Hash(text string) string {
- hasher := md5.New()
- hasher.Write([]byte(text))
- return hex.EncodeToString(hasher.Sum(nil))
-}
-
-// waitForStore waits for the local store to be ready by checking if
-// the schema information is synchronized.
-func waitForStore(storeAddress string) {
- ctx := rt.R().NewContext()
-
- // Register *storage.Entry for WatchGlob.
- // TODO(tilaks): storage.Entry is declared in vdl, vom should register the
- // pointer automatically.
- vom.Register(&storage.Entry{})
-
- fmt.Printf("Waiting for Store to be initialized with fortune schema...\n")
- // List of paths to check in store.
- paths := []string{appPath, fortunePath(""), userPath("")}
- for _, path := range paths {
- abspath := naming.Join(storeAddress, path)
- req := types.GlobRequest{Pattern: ""}
- stream, err := vstore.New().Bind(abspath).WatchGlob(ctx, req)
- if err != nil {
- log.Fatalf("WatchGlob %s failed: %v", abspath, err)
- }
- if !stream.RecvStream().Advance() {
- log.Fatalf("waitForStore (abspath: %s) Advance failed: %v", abspath, stream.RecvStream().Err())
- }
- stream.Cancel()
- }
-
- fmt.Printf("Store is ready\n")
- return
-}
-
-// runAsWatcher monitors updates to the fortunes in the store and
-// prints out that information. It does not return.
-func runAsWatcher(storeAddress string, user string) {
- // TODO(tilaks): remove this when the storage.Entry is auto-registered by VOM.
- vom.Register(&storage.Entry{})
- ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
- defer cancel()
-
- // Monitor all new fortunes or only those of a specific user.
- var path string
- if user == "" {
- path = fortunePath("")
- } else {
- path = userPath(user)
- }
- fmt.Printf("Running as a Watcher monitoring new fortunes under %s...\n", path)
-
- abspath := naming.Join(storeAddress, path)
- req := types.GlobRequest{Pattern: "*"}
- stream, err := vstore.New().Bind(abspath).WatchGlob(ctx, req)
- if err != nil {
- log.Fatalf("watcher WatchGlob %s failed: %v", abspath, err)
- }
-
- rStream := stream.RecvStream()
- for rStream.Advance() {
- change := rStream.Value()
-
- entry, ok := change.Value.(*storage.Entry)
- if !ok {
- log.Printf("watcher change Value not a storage Entry: %#v", change.Value)
- continue
- }
-
- fortune, ok := entry.Value.(schema.FortuneData)
- if !ok {
- log.Printf("watcher data not a FortuneData Entry: %#v", entry.Value)
- continue
- }
-
- fmt.Printf("watcher: new fortune: %s\n", fortune.Fortune)
- }
- err = rStream.Err()
- if err == nil {
- err = io.EOF
- }
- log.Fatalf("watcher Advance failed: %v", err)
-}
-
-// pickFortuneGlob uses Glob to find all available fortunes under the input
-// path and then it chooses one randomly.
-func pickFortuneGlob(storeAddress string, ctx context.T, path string) (string, error) {
- tx := vstore.New().NewTransaction(ctx, storeAddress)
-
- // This transaction is read-only, so we always abort it at the end.
- defer tx.Abort(ctx)
-
- results := tx.Bind(path).Glob(ctx, "*")
- var names []string
- rStream := results.RecvStream()
- for rStream.Advance() {
- names = append(names, rStream.Value())
- }
- if err := results.Err(); err != nil || len(names) == 0 {
- return "", err
- }
-
- // Get a random fortune using the glob results.
- random := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
- p := fortunePath(names[random.Intn(len(names))])
- f, err := tx.Bind(p).Get(ctx)
- if err != nil {
- return "", err
- }
- fortune, ok := f.Value.(schema.FortuneData)
- if !ok {
- return "", fmt.Errorf("found type %T, expected schema.FortuneData", f.Value)
- }
- return fortune.Fortune, nil
-}
-
-// pickFortuneQuery uses a query to find all available fortunes under the input
-// path and choose one randomly.
-func pickFortuneQuery(storeAddress string, ctx context.T, path string) (string, error) {
- abspath := naming.Join(storeAddress, path)
- results := vstore.New().Bind(abspath).Query(ctx,
- query.Query{
- "* |" + // Inspect all children of path.
- "type FortuneData |" + // Include only objects of type FortuneData.
- "{Fortune: Fortune} |" + // Create a new struct containing only the Fortune field.
- "sample(1)", // Randomly select one.
- })
- for results.Advance() {
- f := results.Value().Fields()["Fortune"]
- fortune, ok := f.(string)
- if !ok {
- return "", fmt.Errorf("unexpected type for fortune, got %T, expected string", f)
- }
- results.Cancel()
- return fortune, nil
- }
- if results.Err() != nil {
- return "", results.Err()
- }
- return "", nil // No fortunes found.
-}
-
-// getFortune returns a random fortune corresponding to a UserName if
-// specified. If not, it picks a random fortune.
-func getFortune(storeAddress string, userName string) (string, error) {
- ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
- defer cancel()
-
- var path string
- if userName != "" {
- // Look for a random fortune belonging to UserName.
- path = userPath(userName)
- } else {
- // Look for a random fortune.
- path = fortunePath("")
- }
-
- switch *pickMethod {
- case "glob":
- return pickFortuneGlob(storeAddress, ctx, path)
- case "query":
- return pickFortuneQuery(storeAddress, ctx, path)
- default:
- return "", fmt.Errorf("unsupported value for --pick_method. use 'glob' or 'query'")
- }
-}
-
-// addFortune adds a new fortune to the store and links it to the specified
-// UserName. In this process, if the UserName doesn't exist, a new user is
-// created.
-func addFortune(storeAddress string, fortune string, userName string) error {
- ctx, cancel := rt.R().NewContext().WithTimeout(time.Minute)
- defer cancel()
-
- st := vstore.New()
- tx := st.NewTransaction(ctx, storeAddress)
-
- committed := false
- defer func() {
- if !committed {
- tx.Abort(ctx)
- }
- }()
-
- // Check if this fortune already exists. If yes, return.
- hash := getMD5Hash(naming.Join(fortune, userName))
- exists, err := tx.Bind(fortunePath(hash)).Exists(ctx)
- if err != nil {
- return err
- }
- if exists {
- return nil
- }
-
- // Check if the UserName exists. If yes, get its OID. If not, create a new
- // user.
- o := tx.Bind(userPath(userName))
- exists, err = o.Exists(ctx)
- if err != nil {
- return err
- }
- var userid storage.ID
- if !exists {
- u := schema.User{Name: userName}
- stat, err := o.Put(ctx, u)
- if err != nil {
- return err
- }
- userid = stat.ID
- } else {
- u, err := o.Get(ctx)
- if err != nil {
- return err
- }
- userid = u.Stat.ID
- }
-
- // Create a new fortune entry.
- f := schema.FortuneData{Fortune: fortune, UserName: userid}
- s, err := tx.Bind(fortunePath(hash)).Put(ctx, f)
- if err != nil {
- return err
- }
-
- // Link the new fortune to UserName.
- p := userPath(naming.Join(userName, hash))
- if _, err = tx.Bind(p).Put(ctx, s.ID); err != nil {
- return err
- }
-
- // Commit all changes.
- //
- // NOTE: A commit can sometimes fail due to store's optimistic
- // locking. When the error for this scenario is
- // exposed via the Commit API, one could retry the
- // transaction.
- if err := tx.Commit(ctx); err != nil {
- return err
- }
- committed = true
- return nil
-}
-
-var (
- appPath = "/apps/stfortune"
- storeAddress = flag.String("store", "", "the address/endpoint of the Veyron Store")
- newFortune = flag.String("new_fortune", "", "an optional, new fortune to add to the server's set")
- user = flag.String("user_name", "", "an optional username of the fortune creator to get/add to the server's set")
- watch = flag.Bool("watch", false, "run as a watcher reporting new fortunes")
- pickMethod = flag.String("pick_method", "glob", "use 'glob' or 'query' to randomly select a fortune")
-)
-
-func main() {
- rt.Init()
- if *storeAddress == "" {
- log.Fatal("--store needs to be specified")
- }
-
- // Wait for the store to be ready before proceeding.
- waitForStore(*storeAddress)
-
- // Get a fortune from the store.
- fortune, err := getFortune(*storeAddress, *user)
- if err != nil {
- log.Fatal("error getting fortune: ", err)
- }
- fmt.Println("Fortune: ", fortune)
-
- // If the user specified --new_fortune, add it to the store’s set of fortunes.
- if *newFortune != "" {
- if *user == "" {
- *user = "anonymous"
- }
- *user = strings.ToLower(*user)
- if err := addFortune(*storeAddress, *newFortune, *user); err != nil {
- log.Fatal("error adding fortune: ", err)
- }
- }
-
- // Run as a watcher if --watch is set.
- if *watch {
- runAsWatcher(*storeAddress, *user)
- os.Exit(0)
- }
-}
diff --git a/examples/todos/.gitignore b/examples/todos/.gitignore
deleted file mode 100644
index 25e502e..0000000
--- a/examples/todos/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-node_modules
-npm-debug.log
-todos_appd/node_modules
-todos_appd/public/bundle.*
-todos_appd/third_party/veyron.*
diff --git a/examples/todos/.jshintrc b/examples/todos/.jshintrc
deleted file mode 100644
index 271bb11..0000000
--- a/examples/todos/.jshintrc
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "camelcase": true,
- "curly": true,
- "eqeqeq": true,
- "expr": true,
- "forin": true,
- "freeze": true,
- "immed": true,
- "indent": 2,
- "latedef": "nofunc",
- "maxlen": 80,
- "newcap": true,
- "noarg": true,
- "nonbsp": true,
- "nonew": true,
- "quotmark": "single",
- "sub": true,
- "trailing": true,
- "undef": true,
- "unused": "vars",
-
- "browser": true,
- "devel": true,
- "node": true,
-
- "globals": {
- "$": false,
- "_": false,
- "Backbone": false,
- "React": false
- }
-}
diff --git a/examples/todos/Makefile b/examples/todos/Makefile
deleted file mode 100644
index 3ddf791..0000000
--- a/examples/todos/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-# TODO(sadovsky): Eliminate separate {build,run,watch}app rules once everything
-# is wired together.
-
-export PATH := node_modules/.bin:${VEYRON_ROOT}/environment/cout/node/bin:${PATH}
-
-VEYRON_JS_API := ${VEYRON_ROOT}/veyron/javascript/api
-BUNDLE_JS := todos_appd/public/bundle.js
-
-node_modules:
- npm install
- (cd todos_appd && npm install)
-
-buildgo:
- ${VEYRON_ROOT}/veyron/scripts/build/go install veyron/examples/todos/... veyron/services/mounttable/mounttabled veyron.io/store/veyron/services/store/stored veyron/tools/findunusedport veyron/tools/identity
-
-buildapp: node_modules
- browserify -d todos_appd/browser/*.js -p [minifyify --map bundle.js.map --output ${BUNDLE_JS}.map] -o ${BUNDLE_JS}
-
-build: buildgo buildapp
-
-run: build
- ./run.sh
-
-test:
- ./test.sh
-
-runapp: buildapp
- (cd todos_appd && npm start)
-
-watchapp:
- watch -n 1 make buildapp
-
-gofmt:
- gofmt -w .
-
-clean:
- rm -rf node_modules
- rm -rf todos_appd/node_modules
- rm -rf todos_appd/public/bundle.*
- rm -rf todos_appd/third_party/veyron.*
-
-lint: node_modules
- jshint todos_appd/server.js todos_appd/browser/*.js
-
-.PHONY: buildgo buildapp build run runapp watchapp gofmt clean lint
diff --git a/examples/todos/README.md b/examples/todos/README.md
deleted file mode 100644
index 7ff6183..0000000
--- a/examples/todos/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-todos
-=====
-export VEYRON_ROOT=/usr/local/google/home/sadovsky/veyron
-export PATH=./node_modules/.bin:${VEYRON_ROOT}/environment/cout/node/bin:${PATH}
-
-make build
-make start
-make lint
-
-vgo install {veyron,veyron2}/...
-npm install
-gofmt -w go/src/veyron/examples/todos
-grunt start
diff --git a/examples/todos/package.json b/examples/todos/package.json
deleted file mode 100644
index 431c8ce..0000000
--- a/examples/todos/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "todos",
- "version": "0.0.1",
- "dependencies": {
- "veyron": "git+ssh://git@github.com:veyron/veyron.js.git"
- },
- "devDependencies": {
- "browserify": "^5.9.1",
- "jshint": "^2.5.2",
- "minifyify": "^4.0.3"
- }
-}
diff --git a/examples/todos/run.sh b/examples/todos/run.sh
deleted file mode 100755
index fbda5df..0000000
--- a/examples/todos/run.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/bash
-
-source "${VEYRON_ROOT}/environment/scripts/lib/shell.sh"
-
-trap at_exit INT TERM EXIT
-
-readonly REPO_ROOT=$(git rev-parse --show-toplevel)
-readonly ID_FILE=$(shell::tmp_file)
-readonly DB_DIR=$(shell::tmp_dir)
-
-at_exit() {
- exec 2>/dev/null
- shell::at_exit # deletes ID_FILE and DB_DIR
- kill -9 $(jobs -p) || true
-}
-
-main() {
- # Used by test.sh to get the store viewer port.
- local VIEWER_PORT_FILE=""
- if [[ "$#" -eq 1 ]]; then
- VIEWER_PORT_FILE="$1"
- fi
- local -r VIEWER_PORT_FILE
- local -r VEYRON_BIN="${REPO_ROOT}/go/bin"
-
- # Generate a self-signed identity.
- "${VEYRON_BIN}/identity" generate > "${ID_FILE}"
-
- # Start the mounttable daemon.
- local -r MT_PORT=$("${VEYRON_BIN}/findunusedport")
- "${VEYRON_BIN}/mounttabled" --address="127.0.0.1:${MT_PORT}" &
-
- # Wait for mounttabled to start up.
- sleep 1
-
- export VEYRON_IDENTITY="${ID_FILE}"
- export NAMESPACE_ROOT="/127.0.0.1:${MT_PORT}"
-
- # Start the store daemon.
- local -r VIEWER_PORT=$("${VEYRON_BIN}/findunusedport")
- "${VEYRON_BIN}/stored" --address=127.0.0.1:0 --db="${DB_DIR}" --viewerPort="${VIEWER_PORT}" &
-
- # Wait for stored to start up.
- sleep 1
-
- # Initialize the store with data and templates.
- "${VEYRON_BIN}/todos_init" --data-path=todos_init/data.json
-
- if [[ -n "${VIEWER_PORT_FILE}" ]]; then
- echo "${VIEWER_PORT}" > "${VIEWER_PORT_FILE}"
- fi
-
- echo
- echo "Visit http://localhost:${VIEWER_PORT} to browse the store."
- echo "Hit Ctrl-C to kill all running services."
- wait
-}
-
-main "$@"
diff --git a/examples/todos/schema/init.go b/examples/todos/schema/init.go
deleted file mode 100644
index 9b6695a..0000000
--- a/examples/todos/schema/init.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Package schema defines a schema for a todos application.
-package schema
-
-import (
- "veyron2/vom"
-)
-
-func init() {
- vom.Register(&Dir{})
- vom.Register(&List{})
- vom.Register(&Item{})
-}
diff --git a/examples/todos/schema/schema.vdl b/examples/todos/schema/schema.vdl
deleted file mode 100644
index 9072515..0000000
--- a/examples/todos/schema/schema.vdl
+++ /dev/null
@@ -1,19 +0,0 @@
-package schema
-
-// Dir represents a directory.
-type Dir struct{}
-
-// List is a list of items.
-type List struct {
- Name string
- // Subdirectories:
- //
- // Items/ contains values of type Item.
-}
-
-// Item is a single task to be done.
-type Item struct {
- Text string
- Done bool
- Tags []string
-}
diff --git a/examples/todos/schema/schema.vdl.go b/examples/todos/schema/schema.vdl.go
deleted file mode 100644
index 53cc709..0000000
--- a/examples/todos/schema/schema.vdl.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: schema.vdl
-
-package schema
-
-// Dir represents a directory.
-type Dir struct {
-}
-
-// List is a list of items.
-type List struct {
- Name string
-}
-
-// Item is a single task to be done.
-type Item struct {
- Text string
- Done bool
- Tags []string
-}
diff --git a/examples/todos/test.sh b/examples/todos/test.sh
deleted file mode 100755
index 8f3c6dc..0000000
--- a/examples/todos/test.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-
-# Tests this example.
-#
-# Builds binaries, starts up services, waits a few seconds, then checks that the
-# store browser responds with valid data.
-
-source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
-
-main() {
- # TODO(kash): This test is disabled while we redo the store API.
- shell_test::pass
-
- cd "${REPO_ROOT}/go/src/veyron/examples/todos"
- make buildgo &>/dev/null || shell_test::fail "line ${LINENO}: failed to build"
- local -r VIEWER_PORT_FILE="${TMPDIR}/viewer_port.txt"
- ./run.sh "${VIEWER_PORT_FILE}" &>/dev/null &
-
- sleep 5 # Wait for services to warm up.
-
- if [ ! -f "${VIEWER_PORT_FILE}" ]; then
- shell_test::fail "line ${LINENO}: failed to get viewer url"
- fi
- local -r VIEWER_PORT=$(cat "${VIEWER_PORT_FILE}")
-
- local -r HTML_FILE="${TMPDIR}/index.html"
- local -r URL="http://127.0.0.1:${VIEWER_PORT}"
- curl 2>/dev/null "${URL}" -o "${HTML_FILE}" || shell_test::fail "line ${LINENO}: failed to fetch ${URL}"
-
- if grep -q "/lists" "${HTML_FILE}"; then
- shell_test::pass
- else
- cat "${HTML_FILE}"
- shell_test::fail "line ${LINENO}: fetched page does not meet expectations"
- fi
-}
-
-main "$@"
diff --git a/examples/todos/todos_appd/browser/collection.js b/examples/todos/todos_appd/browser/collection.js
deleted file mode 100644
index 589465a..0000000
--- a/examples/todos/todos_appd/browser/collection.js
+++ /dev/null
@@ -1,136 +0,0 @@
-// TODO: Use minimongo?
-
-'use strict';
-
-module.exports = Collection;
-
-var CHANGE = 'change';
-
-function BaseEvent(type) {
- this.type = type;
-}
-
-function ChangeEvent() {
- BaseEvent.call(this, CHANGE);
-}
-
-function Collection(name) {
- this.name_ = name;
- this.vals_ = [];
-
- this.listeners_ = {};
- this.listeners_[CHANGE] = [];
-}
-
-Collection.prototype = {
- find: function(q, opts) {
- var that = this;
- q = this.normalize_(q);
- var res = _.filter(this.vals_, function(v) {
- return that.matches_(v, q);
- });
- if (opts.sort) {
- // TODO: Eliminate simplifying assumptions.
- var keys = _.keys(opts.sort);
- console.assert(keys.length === 1);
- var key = keys[0];
- console.assert(opts.sort[key] === 1);
- res = res.sort(function(a, b) {
- // TODO: Verify and enhance comparator.
- return a[key] > b[key];
- });
- }
- return _.cloneDeep(res);
- },
- findOne: function(q, opts) {
- var all = this.find(q, opts);
- if (all.length > 0) {
- return all[0];
- }
- return null;
- },
- insert: function(v) {
- console.assert(!_.has(v, '_id'));
- v = _.assign({}, v, {_id: this.vals_.length});
- this.vals_.push(v);
- this.dispatchEvent_(new ChangeEvent());
- return v._id;
- },
- remove: function(q) {
- var that = this;
- q = this.normalize_(q);
- this.vals_ = _.filter(this.vals_, function(v) {
- return !that.matches_(v, q);
- });
- this.dispatchEvent_(new ChangeEvent());
- },
- update: function(q, opts) {
- var that = this;
- q = this.normalize_(q);
- var vals = _.filter(this.vals_, function(v) {
- return that.matches_(v, q);
- });
-
- // TODO: Eliminate simplifying assumptions.
- var keys = _.keys(opts);
- console.assert(keys.length === 1);
- var key = keys[0];
- console.assert(_.contains(['$addToSet', '$pull', '$set'], key));
- var opt = opts[key];
- var fields = _.keys(opt);
- console.assert(keys.length === 1);
- var field = fields[0];
-
- _.each(vals, function(val) {
- switch (key) {
- case '$addToSet':
- val[field] = _.union(val[field], [opt[field]]);
- break;
- case '$pull':
- val[field] = _.without(val[field], opt[field]);
- break;
- case '$set':
- val[field] = opt[field];
- break;
- }
- });
-
- this.dispatchEvent_(new ChangeEvent());
- },
- addEventListener: function(type, handler) {
- this.listeners_[type].push(handler);
- },
- removeEventListener: function(type, handler) {
- this.listeners_[type] = _.without(this.listeners_[type], handler);
- },
- on: function(type, handler) {
- this.addEventListener(type, handler);
- },
- normalize_: function(q) {
- if (_.isObject(q)) {
- return q;
- }
- return {_id: q};
- },
- matches_: function(v, q) {
- var keys = _.keys(q);
- for (var i = 0; i < keys.length; i++) {
- var key = keys[i];
- if (_.isArray(v[key]) && !_.isArray(q[key])) {
- if (!_.contains(v[key], q[key])) {
- return false;
- }
- } else {
- if (q[key] !== v[key]) {
- return false;
- }
- }
- }
- return true;
- },
- dispatchEvent_: function(e) {
- _.each(this.listeners_[e.type], function(handler) {
- handler(e);
- });
- }
-};
diff --git a/examples/todos/todos_appd/browser/defaults.js b/examples/todos/todos_appd/browser/defaults.js
deleted file mode 100644
index 1455103..0000000
--- a/examples/todos/todos_appd/browser/defaults.js
+++ /dev/null
@@ -1,61 +0,0 @@
-'use strict';
-
-var Collection = require('./collection');
-
-var lists = new Collection('lists');
-var todos = new Collection('todos');
-
-// Copied from meteor/todos/server/bootstrap.js.
-var data = [
- {name: 'Meteor Principles',
- contents: [
- ['Data on the Wire', 'Simplicity', 'Better UX', 'Fun'],
- ['One Language', 'Simplicity', 'Fun'],
- ['Database Everywhere', 'Simplicity'],
- ['Latency Compensation', 'Better UX'],
- ['Full Stack Reactivity', 'Better UX', 'Fun'],
- ['Embrace the Ecosystem', 'Fun'],
- ['Simplicity Equals Productivity', 'Simplicity', 'Fun']
- ]
- },
- {name: 'Languages',
- contents: [
- ['Lisp', 'GC'],
- ['C', 'Linked'],
- ['C++', 'Objects', 'Linked'],
- ['Python', 'GC', 'Objects'],
- ['Ruby', 'GC', 'Objects'],
- ['JavaScript', 'GC', 'Objects'],
- ['Scala', 'GC', 'Objects'],
- ['Erlang', 'GC'],
- ['6502 Assembly', 'Linked']
- ]
- },
- {name: 'Favorite Scientists',
- contents: [
- ['Ada Lovelace', 'Computer Science'],
- ['Grace Hopper', 'Computer Science'],
- ['Marie Curie', 'Physics', 'Chemistry'],
- ['Carl Friedrich Gauss', 'Math', 'Physics'],
- ['Nikola Tesla', 'Physics'],
- ['Claude Shannon', 'Math', 'Computer Science']
- ]
- }
-];
-
-var timestamp = (new Date()).getTime();
-for (var i = 0; i < data.length; i++) {
- var listId = lists.insert({name: data[i].name});
- for (var j = 0; j < data[i].contents.length; j++) {
- var info = data[i].contents[j];
- todos.insert({listId: listId,
- text: info[0],
- done: false,
- timestamp: timestamp,
- tags: info.slice(1)});
- timestamp += 1; // ensure unique timestamp
- }
-}
-
-exports.lists = lists;
-exports.todos = todos;
diff --git a/examples/todos/todos_appd/browser/dispatcher.js b/examples/todos/todos_appd/browser/dispatcher.js
deleted file mode 100644
index f2e3d10..0000000
--- a/examples/todos/todos_appd/browser/dispatcher.js
+++ /dev/null
@@ -1,43 +0,0 @@
-// Note, this is a mix of React Actions, Dispatcher, and Stores.
-
-'use strict';
-
-module.exports = Dispatcher;
-
-function Dispatcher(lists, todos) {
- this.lists_ = lists;
- this.todos_ = todos;
-}
-
-Dispatcher.prototype = {
- addList: function(name) {
- return this.lists_.insert({name: name});
- },
- editListName: function(listId, name) {
- this.lists_.update(listId, {$set: {name: name}});
- },
- addTodo: function(listId, text, tags) {
- return this.todos_.insert({
- listId: listId,
- text: text,
- done: false,
- timestamp: (new Date()).getTime(),
- tags: tags
- });
- },
- removeTodo: function(todoId) {
- this.todos_.remove(todoId);
- },
- editTodoText: function(todoId, text) {
- this.todos_.update(todoId, {$set: {text: text}});
- },
- markTodoDone: function(todoId, done) {
- this.todos_.update(todoId, {$set: {done: done}});
- },
- addTag: function(todoId, tag) {
- this.todos_.update(todoId, {$addToSet: {tags: tag}});
- },
- removeTag: function(todoId, tag) {
- this.todos_.update(todoId, {$pull: {tags: tag}});
- }
-};
diff --git a/examples/todos/todos_appd/browser/index.js b/examples/todos/todos_appd/browser/index.js
deleted file mode 100644
index 75123e8..0000000
--- a/examples/todos/todos_appd/browser/index.js
+++ /dev/null
@@ -1,448 +0,0 @@
-'use strict';
-
-var Dispatcher = require('./dispatcher');
-
-////////////////////////////////////////
-// Global state
-
-var defaults = require('./defaults');
-var cLists = defaults.lists;
-var cTodos = defaults.todos;
-
-var d = new Dispatcher(cLists, cTodos);
-
-////////////////////////////////////////
-// Helpers
-
-function activateInput(input) {
- input.focus();
- input.select();
-}
-
-function okCancelEvents(callbacks) {
- var ok = callbacks.ok || function() {};
- var cancel = callbacks.cancel || function() {};
- function done(ev) {
- var value = ev.target.value;
- if (value) {
- ok(value, ev);
- } else {
- cancel(ev);
- }
- }
- return {
- onKeyDown: function(ev) {
- if (ev.which === 27) { // esc
- cancel(ev);
- }
- },
- onKeyUp: function(ev) {
- if (ev.which === 13) { // enter
- done(ev);
- }
- },
- onBlur: function(ev) {
- done(ev);
- }
- };
-}
-
-////////////////////////////////////////
-// Components
-
-var TagFilter = React.createClass({
- displayName: 'TagFilter',
- render: function() {
- var that = this;
- var tagFilter = this.props.tagFilter;
- var tagInfos = [], totalCount = 0;
- _.each(this.props.todos, function(todo) {
- _.each(todo.tags, function(tag) {
- var tagInfo = _.find(tagInfos, function(x) {
- return x.tag === tag;
- });
- if (!tagInfo) {
- tagInfos.push({tag: tag, count: 1, selected: tagFilter === tag});
- } else {
- tagInfo.count++;
- }
- });
- totalCount++;
- });
- tagInfos = _.sortBy(tagInfos, function(x) { return x.tag; });
- // Note, the 'All items' tag handling is fairly convoluted in Meteor.
- tagInfos.unshift({
- tag: null,
- count: totalCount,
- selected: tagFilter === null
- });
-
- var children = [];
- _.each(tagInfos, function(tagInfo) {
- var count = React.DOM.span(
- {className: 'count'}, '(' + tagInfo.count + ')');
- children.push(React.DOM.div({
- className: 'tag' + (tagInfo.selected ? ' selected' : ''),
- onMouseDown: function() {
- var newTagFilter = tagFilter === tagInfo.tag ? null : tagInfo.tag;
- that.props.setTagFilter(newTagFilter);
- }
- }, tagInfo.tag === null ? 'All items' : tagInfo.tag, ' ', count));
- });
- return React.DOM.div(
- {id: 'tag-filter', className: 'tag-list'},
- React.DOM.div({className: 'label'}, 'Show:'),
- children);
- }
-});
-
-var Tags = React.createClass({
- displayName: 'Tags',
- getInitialState: function() {
- return {
- addingTag: false
- };
- },
- componentDidUpdate: function() {
- if (this.state.addingTag) {
- activateInput(this.getDOMNode().querySelector('#edittag-input'));
- }
- },
- render: function() {
- var that = this;
- var children = [];
- _.each(this.props.tags, function(tag) {
- // Note, we must specify the "key" prop so that React doesn't reuse the
- // opacity=0 node after a tag is removed.
- children.push(React.DOM.div(
- {className: 'tag removable_tag', key: tag},
- React.DOM.div({className: 'name'}, tag),
- React.DOM.div({
- className: 'remove',
- onClick: function(ev) {
- ev.target.parentNode.style.opacity = 0;
- // Wait for CSS animation to finish.
- window.setTimeout(function() {
- d.removeTag(that.props.todoId, tag);
- }, 300);
- }
- })));
- });
- if (this.state.addingTag) {
- children.push(React.DOM.div(
- {className: 'tag edittag'},
- React.DOM.input(_.assign({
- type: 'text',
- id: 'edittag-input',
- defaultValue: ''
- }, okCancelEvents({
- ok: function(value) {
- d.addTag(that.props.todoId, value);
- that.setState({addingTag: false});
- },
- cancel: function() {
- that.setState({addingTag: false});
- }
- })))));
- } else {
- children.push(React.DOM.div({
- className: 'tag addtag',
- onClick: function() {
- that.setState({addingTag: true});
- }
- }, '+tag'));
- }
- return React.DOM.div({className: 'item-tags'}, children);
- }
-});
-
-var Todo = React.createClass({
- displayName: 'Todo',
- getInitialState: function() {
- return {
- editingText: false
- };
- },
- componentDidUpdate: function() {
- if (this.state.editingText) {
- activateInput(this.getDOMNode().querySelector('#todo-input'));
- }
- },
- render: function() {
- var that = this;
- var todo = this.props.todo, children = [];
- if (this.state.editingText) {
- children.push(React.DOM.div(
- {className: 'edit'},
- React.DOM.input(_.assign({
- id: 'todo-input',
- type: 'text',
- defaultValue: todo.text
- }, okCancelEvents({
- ok: function(value) {
- d.editTodoText(todo._id, value);
- that.setState({editingText: false});
- },
- cancel: function() {
- that.setState({editingText: false});
- }
- })))));
- } else {
- children.push(React.DOM.div({
- className: 'destroy',
- onClick: function() {
- d.removeTodo(todo._id);
- }
- }));
- children.push(React.DOM.div(
- {className: 'display'},
- React.DOM.input({
- className: 'check',
- name: 'markdone',
- type: 'checkbox',
- checked: todo.done,
- onClick: function() {
- d.markTodoDone(!todo.done);
- }
- }),
- React.DOM.div({
- className: 'todo-text',
- onDoubleClick: function() {
- that.setState({editingText: true});
- }
- }, todo.text)));
- }
- children.push(new Tags({todoId: todo._id, tags: todo.tags}));
- return React.DOM.li({
- className: 'todo' + (todo.done ? ' done' : '')
- }, children);
- }
-});
-
-var Todos = React.createClass({
- displayName: 'Todos',
- render: function() {
- var that = this;
- if (this.props.listId === null) {
- return null;
- }
- var children = [];
- if (this.props.todos === null) {
- children.push('Loading...');
- } else {
- var tagFilter = this.props.tagFilter, items = [];
- _.each(this.props.todos, function(todo) {
- if (tagFilter === null || _.contains(todo.tags, tagFilter)) {
- items.push(new Todo({todo: todo}));
- }
- });
- children.push(React.DOM.div(
- {id: 'new-todo-box'},
- React.DOM.input(_.assign({
- type: 'text',
- id: 'new-todo',
- placeholder: 'New item'
- }, okCancelEvents({
- ok: function(value, ev) {
- var tags = tagFilter ? [tagFilter] : [];
- d.addTodo(that.props.listId, value, tags);
- ev.target.value = '';
- }
- })))));
- children.push(React.DOM.ul({id: 'item-list'}, items));
- }
- return React.DOM.div({id: 'items-view'}, children);
- }
-});
-
-var List = React.createClass({
- displayName: 'List',
- getInitialState: function() {
- return {
- editingName: false
- };
- },
- componentDidUpdate: function() {
- if (this.state.editingName) {
- activateInput(this.getDOMNode().querySelector('#list-name-input'));
- }
- },
- render: function() {
- var that = this;
- var list = this.props.list, child;
- // http://facebook.github.io/react/docs/forms.html#controlled-components
- if (this.state.editingName) {
- child = React.DOM.div(
- {className: 'edit'},
- React.DOM.input(_.assign({
- className: 'list-name-input',
- id: 'list-name-input',
- type: 'text',
- defaultValue: list.name
- }, okCancelEvents({
- ok: function(value) {
- d.editListName(list._id, value);
- that.setState({editingName: false});
- },
- cancel: function() {
- that.setState({editingName: false});
- }
- }))));
- } else {
- child = React.DOM.div(
- {className: 'display'},
- React.DOM.a({
- className: 'list-name' + (list.name ? '' : ' empty'),
- href: '/lists/' + list._id
- }, list.name));
- }
- return React.DOM.div({
- className: 'list' + (list.selected ? ' selected' : ''),
- onMouseDown: function() {
- that.props.setListId(list._id);
- },
- onClick: function(ev) {
- ev.preventDefault(); // prevent page refresh
- },
- onDoubleClick: function() {
- that.setState({editingName: true});
- }
- }, child);
- }
-});
-
-var Lists = React.createClass({
- displayName: 'Lists',
- render: function() {
- var that = this;
- var children = [React.DOM.h3({}, 'Todo Lists')];
- if (this.props.lists === null) {
- children.push(React.DOM.div({id: 'lists'}, 'Loading...'));
- } else {
- var lists = [];
- _.each(this.props.lists, function(list) {
- list.selected = that.props.listId === list._id;
- lists.push(new List({
- list: list,
- setListId: that.props.setListId
- }));
- });
- children.push(React.DOM.div({id: 'lists'}, lists));
- children.push(React.DOM.div(
- {id: 'createList'},
- React.DOM.input(_.assign({
- type: 'text',
- id: 'new-list',
- placeholder: 'New list'
- }, okCancelEvents({
- ok: function(value, ev) {
- var id = d.addList(value);
- that.props.setListId(id);
- ev.target.value = '';
- }
- })))));
- }
- return React.DOM.div({}, children);
- }
-});
-
-var Page = React.createClass({
- displayName: 'Page',
- getInitialState: function() {
- return {
- lists: null, // all lists
- todos: null, // all todos for current listId
- listId: this.props.initialListId, // current list
- tagFilter: null // current tag
- };
- },
- fetchLists: function() {
- return cLists.find({}, {sort: {name: 1}});
- },
- fetchTodos: function(listId) {
- if (listId === null) {
- return null;
- }
- return cTodos.find({listId: listId}, {sort: {timestamp: 1}});
- },
- updateURL: function() {
- var router = this.props.router, listId = this.state.listId;
- router.navigate(listId === null ? '' : '/lists/' + String(listId));
- },
- componentDidMount: function() {
- var that = this;
- var lists = this.fetchLists();
- var listId = this.state.listId;
- if (listId === null && lists.length > 0) {
- listId = lists[0]._id;
- }
- this.setState({
- lists: lists,
- todos: this.fetchTodos(listId),
- listId: listId
- });
- this.updateURL();
-
- cLists.on('change', function() {
- that.setState({lists: that.fetchLists()});
- });
- cTodos.on('change', function() {
- that.setState({todos: that.fetchTodos(that.state.listId)});
- });
- },
- componentDidUpdate: function() {
- this.updateURL();
- },
- render: function() {
- var that = this;
- return React.DOM.div({}, [
- React.DOM.div({id: 'top-tag-filter'}, new TagFilter({
- todos: this.state.todos,
- tagFilter: this.state.tagFilter,
- setTagFilter: function(tagFilter) {
- that.setState({tagFilter: tagFilter});
- }
- })),
- React.DOM.div({id: 'main-pane'}, new Todos({
- todos: this.state.todos,
- listId: this.state.listId,
- tagFilter: this.state.tagFilter
- })),
- React.DOM.div({id: 'side-pane'}, new Lists({
- lists: this.state.lists,
- listId: this.state.listId,
- setListId: function(listId) {
- if (listId !== that.state.listId) {
- that.setState({
- todos: that.fetchTodos(listId),
- listId: listId
- });
- }
- }
- }))
- ]);
- }
-});
-
-////////////////////////////////////////
-// UI initialization
-
-var Router = Backbone.Router.extend({
- routes: {
- '': 'main',
- 'lists/:listId': 'main'
- }
-});
-var router = new Router();
-
-var page;
-router.on('route:main', function(listId) {
- console.assert(!page);
- if (listId !== null) {
- listId = parseInt(listId, 10);
- }
- page = new Page({router: router, initialListId: listId});
- React.renderComponent(page, document.getElementById('c'));
-});
-
-Backbone.history.start({pushState: true});
diff --git a/examples/todos/todos_appd/index.html b/examples/todos/todos_appd/index.html
deleted file mode 100644
index 0edab81..0000000
--- a/examples/todos/todos_appd/index.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="stylesheet" href="/public/index.css">
- <title>Todos</title>
- </head>
- <body>
- <div id="c"></div>
- <script src="/third_party/jquery-2.1.1.min.js"></script>
- <script src="/third_party/lodash.min.js"></script>
- <script src="/third_party/backbone-min.js"></script>
- <!--<script src="public/third_party/react-0.11.1.min.js"></script>-->
- <script src="/third_party/react-0.11.1.js"></script>
- <script src="/public/bundle.js"></script>
- </body>
-</html>
diff --git a/examples/todos/todos_appd/package.json b/examples/todos/todos_appd/package.json
deleted file mode 100644
index 4832279..0000000
--- a/examples/todos/todos_appd/package.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "todos_appd",
- "version": "0.0.1",
- "dependencies": {
- "express": "^4.6.1"
- }
-}
diff --git a/examples/todos/todos_appd/public/close_16.png b/examples/todos/todos_appd/public/close_16.png
deleted file mode 100644
index 5c4cd27..0000000
--- a/examples/todos/todos_appd/public/close_16.png
+++ /dev/null
Binary files differ
diff --git a/examples/todos/todos_appd/public/destroy.png b/examples/todos/todos_appd/public/destroy.png
deleted file mode 100644
index 7ab5432..0000000
--- a/examples/todos/todos_appd/public/destroy.png
+++ /dev/null
Binary files differ
diff --git a/examples/todos/todos_appd/public/index.css b/examples/todos/todos_appd/public/index.css
deleted file mode 100644
index 6b21348..0000000
--- a/examples/todos/todos_appd/public/index.css
+++ /dev/null
@@ -1,262 +0,0 @@
-* {
- padding: 0;
- margin: 0;
-}
-
-ul {
- list-style: none;
-}
-
-html, body {
- height: 100%;
-}
-
-body {
- font-size: 16px;
- line-height: 1.5;
- background: #eeeeee;
- color: #333333;
-}
-
-body, input {
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-}
-
-input {
- font-size: 100%;
-}
-
-a, a:visited, a:active {
- color: #258;
-}
-
-h3 {
- font-weight: bold;
- text-decoration: underline;
- font-size: 120%;
- padding: 8px 6px;
- text-align: center;
-}
-
-#top-tag-filter, #main-pane, #side-pane, #bottom-pane {
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- overflow: hidden;
-}
-
-#top-tag-filter {
- left: 200px;
- height: 44px;
- bottom: auto;
- background: #ddd;
- border-bottom: 1px solid #999;
-}
-
-#help {
- padding: 8px;
-}
-
-#main-pane {
- top: 45px;
- bottom: 0;
- left: 220px;
- overflow: auto;
-}
-
-#side-pane {
- width: 200px;
- right: auto;
- overflow: auto;
- background: #eee;
- border-right: 1px solid #999;
- background: #ddd;
-}
-
-.tag {
- cursor: pointer;
- float: left;
- margin: 5px;
- padding: 2px 7px;
- font-size: 80%;
- font-weight: bold;
- background: #999;
- color: #fff;
- border-radius: 4px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- -o-border-radius: 4px;
-
- opacity: 1;
- transition: opacity 0.3s linear;
- -moz-transition: opacity 0.3s linear;
- -webkit-transition: opacity 0.3s linear;
- -o-transition: opacity 0.3s linear;
-
- position: relative;
-}
-
-#tag-filter .label {
- float: left;
- margin-top: 9px;
- margin-left: 12px;
- margin-right: 8px;
-}
-
-#tag-filter .tag {
- margin-top: 10px;
- border: 1px solid #777;
-}
-
-#tag-filter .selected {
- background: #69d;
-}
-
-#tag-filter .count {
- font-weight: normal;
- padding-left: 2px;
-}
-
-#lists .list {
- padding: 3px 6px;
-}
-
-#lists .selected {
- padding: 2px 6px;
- background: #9be;
- font-weight: bold;
-}
-
-#lists .list-name {
- cursor: pointer;
- color: black;
- text-decoration: none;
-}
-
-#createList {
- padding: 3px 6px;
- margin-top: 5px;
-}
-
-#createList input {
- width: 180px;
-}
-
-#new-todo-box {
- margin-top: 10px;
- margin-bottom: 10px;
- margin-left: 60px;
- margin-right: 20px;
- font-size: 160%;
- position: relative;
- height: 40px;
-}
-
-#new-todo {
- position: absolute;
- width: 100%;
-}
-
-#items-view {
- margin-top: 5px;
- margin-left: 5px;
-}
-
-#item-list .todo {
- display: block;
- height: 50px;
- position: relative;
- overflow: hidden;
- border-top: 1px solid #ccc;
-}
-
-#item-list .todo .destroy {
- cursor: pointer;
- position: absolute;
- left: 5px;
- top: 15px;
- height: 20px;
- width: 20px;
-}
-
-#item-list .todo .display, #item-list .todo .edit {
- margin-left: 30px;
- height: 100%;
- width: auto;
- float: left;
- padding-top: 18px;
- line-height: 1;
-}
-
-#todo-input {
- width: 300px;
- position: relative;
- top: -3px;
-}
-
-#item-list .done .todo-text {
- text-decoration: line-through;
- color: #999;
-}
-
-#item-list .todo:hover .destroy {
- background: url("/public/destroy.png") no-repeat 0 0;
-}
-
-#item-list .todo .destroy:hover {
- background-position: 0 -20px;
-}
-
-#item-list .todo .item-tags {
- overflow: auto;
- float: right;
- margin-right: 8px;
-}
-
-#item-list .todo .item-tags .tag {
- margin-top: 15px;
-}
-
-#item-list .todo .item-tags .removable_tag {
- padding-right: 22px;
-}
-
-#item-list .todo .item-tags .tag .remove {
- position: absolute;
- top: 0;
- right: 4px;
- bottom: 0;
- width: 16px;
- background: url("/public/close_16.png") no-repeat 0 center;
-}
-
-#item-list .todo .item-tags .tag .remove:hover {
- background-position: -16px center;
-}
-
-#item-list .todo .item-tags div.addtag {
- background: none;
- color: #333;
- border: 1px dashed #999;
-}
-
-#item-list .todo .check {
- float: left;
- width: 25px;
-}
-
-#item-list .todo .todo-text {
- float: left;
- margin-left: 10px;
- font-size: 100%;
-}
-
-#item-list .todo .edit input {
- margin-left: 35px;
-}
-
-#edittag-input {
- width: 80px;
-}
diff --git a/examples/todos/todos_appd/server.js b/examples/todos/todos_appd/server.js
deleted file mode 100644
index 9abd8c4..0000000
--- a/examples/todos/todos_appd/server.js
+++ /dev/null
@@ -1,25 +0,0 @@
-'use strict';
-
-var express = require('express');
-var pathlib = require('path');
-
-var app = express();
-
-function pathTo(path) {
- return pathlib.join(__dirname, path);
-}
-
-app.use('/public', express.static(pathTo('public')));
-app.use('/third_party', express.static(pathTo('third_party')));
-
-var routes = ['/', '/lists/*'];
-var handler = function(req, res) {
- res.sendfile('index.html');
-};
-for (var i = 0; i < routes.length; i++) {
- app.get(routes[i], handler);
-}
-
-var server = app.listen(4000, function() {
- console.log('Serving http://localhost:%d', server.address().port);
-});
diff --git a/examples/todos/todos_appd/third_party/backbone-min.js b/examples/todos/todos_appd/third_party/backbone-min.js
deleted file mode 100644
index 8ea4b13..0000000
--- a/examples/todos/todos_appd/third_party/backbone-min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-(function(t,e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){t.Backbone=e(t,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore");e(t,exports,i)}else{t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}})(this,function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.push;var o=n.slice;var h=n.splice;e.VERSION="1.1.2";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var u=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,r){if(!c(this,"once",t,[e,r])||!e)return this;var s=this;var n=i.once(function(){s.off(t,n);e.apply(this,arguments)});n._callback=e;return this.on(t,n,r)},off:function(t,e,r){var s,n,a,o,h,u,l,f;if(!this._events||!c(this,"off",t,[e,r]))return this;if(!t&&!e&&!r){this._events=void 0;return this}o=t?[t]:i.keys(this._events);for(h=0,u=o.length;h<u;h++){t=o[h];if(a=this._events[t]){this._events[t]=s=[];if(e||r){for(l=0,f=a.length;l<f;l++){n=a[l];if(e&&e!==n.callback&&e!==n.callback._callback||r&&r!==n.context){s.push(n)}}}if(!s.length)delete this._events[t]}}return this},trigger:function(t){if(!this._events)return this;var e=o.call(arguments,1);if(!c(this,"trigger",t,e))return this;var i=this._events[t];var r=this._events.all;if(i)f(i,e);if(r)f(r,arguments);return this},stopListening:function(t,e,r){var s=this._listeningTo;if(!s)return this;var n=!e&&!r;if(!r&&typeof e==="object")r=this;if(t)(s={})[t._listenId]=t;for(var a in s){t=s[a];t.off(e,r,this);if(n||i.isEmpty(t._events))delete this._listeningTo[a]}return this}};var l=/\s+/;var c=function(t,e,i,r){if(!i)return true;if(typeof i==="object"){for(var s in i){t[e].apply(t,[s,i[s]].concat(r))}return false}if(l.test(i)){var n=i.split(l);for(var a=0,o=n.length;a<o;a++){t[e].apply(t,[n[a]].concat(r))}return false}return true};var f=function(t,e){var i,r=-1,s=t.length,n=e[0],a=e[1],o=e[2];switch(e.length){case 0:while(++r<s)(i=t[r]).callback.call(i.ctx);return;case 1:while(++r<s)(i=t[r]).callback.call(i.ctx,n);return;case 2:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a);return;case 3:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a,o);return;default:while(++r<s)(i=t[r]).callback.apply(i.ctx,e);return}};var d={listenTo:"on",listenToOnce:"once"};i.each(d,function(t,e){u[e]=function(e,r,s){var n=this._listeningTo||(this._listeningTo={});var a=e._listenId||(e._listenId=i.uniqueId("l"));n[a]=e;if(!s&&typeof r==="object")s=this;e[t](r,s,this);return this}});u.bind=u.on;u.unbind=u.off;i.extend(e,u);var p=e.Model=function(t,e){var r=t||{};e||(e={});this.cid=i.uniqueId("c");this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)r=this.parse(r,e)||{};r=i.defaults({},r,i.result(this,"defaults"));this.set(r,e);this.changed={};this.initialize.apply(this,arguments)};i.extend(p.prototype,u,{changed:null,validationError:null,idAttribute:"id",initialize:function(){},toJSON:function(t){return i.clone(this.attributes)},sync:function(){return e.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return i.escape(this.get(t))},has:function(t){return this.get(t)!=null},set:function(t,e,r){var s,n,a,o,h,u,l,c;if(t==null)return this;if(typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r||(r={});if(!this._validate(n,r))return false;a=r.unset;h=r.silent;o=[];u=this._changing;this._changing=true;if(!u){this._previousAttributes=i.clone(this.attributes);this.changed={}}c=this.attributes,l=this._previousAttributes;if(this.idAttribute in n)this.id=n[this.idAttribute];for(s in n){e=n[s];if(!i.isEqual(c[s],e))o.push(s);if(!i.isEqual(l[s],e)){this.changed[s]=e}else{delete this.changed[s]}a?delete c[s]:c[s]=e}if(!h){if(o.length)this._pending=r;for(var f=0,d=o.length;f<d;f++){this.trigger("change:"+o[f],this,c[o[f]],r)}}if(u)return this;if(!h){while(this._pending){r=this._pending;this._pending=false;this.trigger("change",this,r)}}this._pending=false;this._changing=false;return this},unset:function(t,e){return this.set(t,void 0,i.extend({},e,{unset:true}))},clear:function(t){var e={};for(var r in this.attributes)e[r]=void 0;return this.set(e,i.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!i.isEmpty(this.changed);return i.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?i.clone(this.changed):false;var e,r=false;var s=this._changing?this._previousAttributes:this.attributes;for(var n in t){if(i.isEqual(s[n],e=t[n]))continue;(r||(r={}))[n]=e}return r},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return i.clone(this._previousAttributes)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=this;var r=t.success;t.success=function(i){if(!e.set(e.parse(i,t),t))return false;if(r)r(e,i,t);e.trigger("sync",e,i,t)};q(this,t);return this.sync("read",this,t)},save:function(t,e,r){var s,n,a,o=this.attributes;if(t==null||typeof t==="object"){s=t;r=e}else{(s={})[t]=e}r=i.extend({validate:true},r);if(s&&!r.wait){if(!this.set(s,r))return false}else{if(!this._validate(s,r))return false}if(s&&r.wait){this.attributes=i.extend({},o,s)}if(r.parse===void 0)r.parse=true;var h=this;var u=r.success;r.success=function(t){h.attributes=o;var e=h.parse(t,r);if(r.wait)e=i.extend(s||{},e);if(i.isObject(e)&&!h.set(e,r)){return false}if(u)u(h,t,r);h.trigger("sync",h,t,r)};q(this,r);n=this.isNew()?"create":r.patch?"patch":"update";if(n==="patch")r.attrs=s;a=this.sync(n,this,r);if(s&&r.wait)this.attributes=o;return a},destroy:function(t){t=t?i.clone(t):{};var e=this;var r=t.success;var s=function(){e.trigger("destroy",e,e.collection,t)};t.success=function(i){if(t.wait||e.isNew())s();if(r)r(e,i,t);if(!e.isNew())e.trigger("sync",e,i,t)};if(this.isNew()){t.success();return false}q(this,t);var n=this.sync("delete",this,t);if(!t.wait)s();return n},url:function(){var t=i.result(this,"urlRoot")||i.result(this.collection,"url")||M();if(this.isNew())return t;return t.replace(/([^\/])$/,"$1/")+encodeURIComponent(this.id)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},i.extend(t||{},{validate:true}))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=i.extend({},this.attributes,t);var r=this.validationError=this.validate(t,e)||null;if(!r)return true;this.trigger("invalid",this,r,i.extend(e,{validationError:r}));return false}});var v=["keys","values","pairs","invert","pick","omit"];i.each(v,function(t){p.prototype[t]=function(){var e=o.call(arguments);e.unshift(this.attributes);return i[t].apply(i,e)}});var g=e.Collection=function(t,e){e||(e={});if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,i.extend({silent:true},e))};var m={add:true,remove:true,merge:true};var y={add:true,remove:false};i.extend(g.prototype,u,{model:p,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return e.sync.apply(this,arguments)},add:function(t,e){return this.set(t,i.extend({merge:false},e,y))},remove:function(t,e){var r=!i.isArray(t);t=r?[t]:i.clone(t);e||(e={});var s,n,a,o;for(s=0,n=t.length;s<n;s++){o=t[s]=this.get(t[s]);if(!o)continue;delete this._byId[o.id];delete this._byId[o.cid];a=this.indexOf(o);this.models.splice(a,1);this.length--;if(!e.silent){e.index=a;o.trigger("remove",o,this,e)}this._removeReference(o,e)}return r?t[0]:t},set:function(t,e){e=i.defaults({},e,m);if(e.parse)t=this.parse(t,e);var r=!i.isArray(t);t=r?t?[t]:[]:i.clone(t);var s,n,a,o,h,u,l;var c=e.at;var f=this.model;var d=this.comparator&&c==null&&e.sort!==false;var v=i.isString(this.comparator)?this.comparator:null;var g=[],y=[],_={};var b=e.add,w=e.merge,x=e.remove;var E=!d&&b&&x?[]:false;for(s=0,n=t.length;s<n;s++){h=t[s]||{};if(h instanceof p){a=o=h}else{a=h[f.prototype.idAttribute||"id"]}if(u=this.get(a)){if(x)_[u.cid]=true;if(w){h=h===o?o.attributes:h;if(e.parse)h=u.parse(h,e);u.set(h,e);if(d&&!l&&u.hasChanged(v))l=true}t[s]=u}else if(b){o=t[s]=this._prepareModel(h,e);if(!o)continue;g.push(o);this._addReference(o,e)}o=u||o;if(E&&(o.isNew()||!_[o.id]))E.push(o);_[o.id]=true}if(x){for(s=0,n=this.length;s<n;++s){if(!_[(o=this.models[s]).cid])y.push(o)}if(y.length)this.remove(y,e)}if(g.length||E&&E.length){if(d)l=true;this.length+=g.length;if(c!=null){for(s=0,n=g.length;s<n;s++){this.models.splice(c+s,0,g[s])}}else{if(E)this.models.length=0;var k=E||g;for(s=0,n=k.length;s<n;s++){this.models.push(k[s])}}}if(l)this.sort({silent:true});if(!e.silent){for(s=0,n=g.length;s<n;s++){(o=g[s]).trigger("add",o,this,e)}if(l||E&&E.length)this.trigger("sort",this,e)}return r?t[0]:t},reset:function(t,e){e||(e={});for(var r=0,s=this.models.length;r<s;r++){this._removeReference(this.models[r],e)}e.previousModels=this.models;this._reset();t=this.add(t,i.extend({silent:true},e));if(!e.silent)this.trigger("reset",this,e);return t},push:function(t,e){return this.add(t,i.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);this.remove(e,t);return e},unshift:function(t,e){return this.add(t,i.extend({at:0},e))},shift:function(t){var e=this.at(0);this.remove(e,t);return e},slice:function(){return o.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;return this._byId[t]||this._byId[t.id]||this._byId[t.cid]},at:function(t){return this.models[t]},where:function(t,e){if(i.isEmpty(t))return e?void 0:[];return this[e?"find":"filter"](function(e){for(var i in t){if(t[i]!==e.get(i))return false}return true})},findWhere:function(t){return this.where(t,true)},sort:function(t){if(!this.comparator)throw new Error("Cannot sort a set without a comparator");t||(t={});if(i.isString(this.comparator)||this.comparator.length===1){this.models=this.sortBy(this.comparator,this)}else{this.models.sort(i.bind(this.comparator,this))}if(!t.silent)this.trigger("sort",this,t);return this},pluck:function(t){return i.invoke(this.models,"get",t)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=t.success;var r=this;t.success=function(i){var s=t.reset?"reset":"set";r[s](i,t);if(e)e(r,i,t);r.trigger("sync",r,i,t)};q(this,t);return this.sync("read",this,t)},create:function(t,e){e=e?i.clone(e):{};if(!(t=this._prepareModel(t,e)))return false;if(!e.wait)this.add(t,e);var r=this;var s=e.success;e.success=function(t,i){if(e.wait)r.add(t,e);if(s)s(t,i,e)};t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models)},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(t instanceof p)return t;e=e?i.clone(e):{};e.collection=this;var r=new this.model(t,e);if(!r.validationError)return r;this.trigger("invalid",this,r.validationError,e);return false},_addReference:function(t,e){this._byId[t.cid]=t;if(t.id!=null)this._byId[t.id]=t;if(!t.collection)t.collection=this;t.on("all",this._onModelEvent,this)},_removeReference:function(t,e){if(this===t.collection)delete t.collection;t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if((t==="add"||t==="remove")&&i!==this)return;if(t==="destroy")this.remove(e,r);if(e&&t==="change:"+e.idAttribute){delete this._byId[e.previous(e.idAttribute)];if(e.id!=null)this._byId[e.id]=e}this.trigger.apply(this,arguments)}});var _=["forEach","each","map","collect","reduce","foldl","inject","reduceRight","foldr","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max","min","toArray","size","first","head","take","initial","rest","tail","drop","last","without","difference","indexOf","shuffle","lastIndexOf","isEmpty","chain","sample"];i.each(_,function(t){g.prototype[t]=function(){var e=o.call(arguments);e.unshift(this.models);return i[t].apply(i,e)}});var b=["groupBy","countBy","sortBy","indexBy"];i.each(b,function(t){g.prototype[t]=function(e,r){var s=i.isFunction(e)?e:function(t){return t.get(e)};return i[t](this.models,s,r)}});var w=e.View=function(t){this.cid=i.uniqueId("view");t||(t={});i.extend(this,i.pick(t,E));this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()};var x=/^(\S+)\s*(.*)$/;var E=["model","collection","el","id","attributes","className","tagName","events"];i.extend(w.prototype,u,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();this.stopListening();return this},setElement:function(t,i){if(this.$el)this.undelegateEvents();this.$el=t instanceof e.$?t:e.$(t);this.el=this.$el[0];if(i!==false)this.delegateEvents();return this},delegateEvents:function(t){if(!(t||(t=i.result(this,"events"))))return this;this.undelegateEvents();for(var e in t){var r=t[e];if(!i.isFunction(r))r=this[t[e]];if(!r)continue;var s=e.match(x);var n=s[1],a=s[2];r=i.bind(r,this);n+=".delegateEvents"+this.cid;if(a===""){this.$el.on(n,r)}else{this.$el.on(n,a,r)}}return this},undelegateEvents:function(){this.$el.off(".delegateEvents"+this.cid);return this},_ensureElement:function(){if(!this.el){var t=i.extend({},i.result(this,"attributes"));if(this.id)t.id=i.result(this,"id");if(this.className)t["class"]=i.result(this,"className");var r=e.$("<"+i.result(this,"tagName")+">").attr(t);this.setElement(r,false)}else{this.setElement(i.result(this,"el"),false)}}});e.sync=function(t,r,s){var n=T[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||M()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}if(a.type==="PATCH"&&k){a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var h=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,h,s);return h};var k=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var H=/(\(\?)?:\w+/g;var A=/\*\w+/g;var I=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,u,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);n.execute(s,a);n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)});return this},execute:function(t,e){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(I,"\\$&").replace(S,"(?:$1)?").replace(H,function(t,e){return e?t:"([^/?]+)"}).replace(A,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var N=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var R=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/#.*$/;N.started=false;i.extend(N.prototype,u,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(R,"")},start:function(t){if(N.started)throw new Error("Backbone.history has already been started");N.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var r=this.getFragment();var s=document.documentMode;var n=P.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);this.root=("/"+this.root+"/").replace(O,"/");if(n&&this._wantsHashChange){var a=e.$('<iframe src="javascript:0" tabindex="-1">');this.iframe=a.hide().appendTo("body")[0].contentWindow;this.navigate(r)}if(this._hasPushState){e.$(window).on("popstate",this.checkUrl)}else if(this._wantsHashChange&&"onhashchange"in window&&!n){e.$(window).on("hashchange",this.checkUrl)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}this.fragment=r;var o=this.location;if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){this.fragment=this.getFragment(null,true);this.location.replace(this.root+"#"+this.fragment);return true}else if(this._hasPushState&&this.atRoot()&&o.hash){this.fragment=this.getHash().replace(R,"");this.history.replaceState({},document.title,this.root+this.fragment)}}if(!this.options.silent)return this.loadUrl()},stop:function(){e.$(window).off("popstate",this.checkUrl).off("hashchange",this.checkUrl);if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);N.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getFragment(this.getHash(this.iframe))}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){t=this.fragment=this.getFragment(t);return i.any(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!N.started)return false;if(!e||e===true)e={trigger:!!e};var i=this.root+(t=this.getFragment(t||""));t=t.replace(j,"");if(this.fragment===t)return;this.fragment=t;if(t===""&&i!=="/")i=i.slice(0,-1);if(this._hasPushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,i)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getFragment(this.getHash(this.iframe))){if(!e.replace)this.iframe.document.open().close();this._updateHash(this.iframe.location,t,e.replace)}}else{return this.location.assign(i)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});e.history=new N;var U=function(t,e){var r=this;var s;if(t&&i.has(t,"constructor")){s=t.constructor}else{s=function(){return r.apply(this,arguments)}}i.extend(s,r,e);var n=function(){this.constructor=s};n.prototype=r.prototype;s.prototype=new n;if(t)i.extend(s.prototype,t);s.__super__=r.prototype;return s};p.extend=g.extend=$.extend=w.extend=N.extend=U;var M=function(){throw new Error('A "url" property or function must be specified')};var q=function(t,e){var i=e.error;e.error=function(r){if(i)i(t,r,e);t.trigger("error",t,r,e)}};return e});
-//# sourceMappingURL=backbone-min.map
\ No newline at end of file
diff --git a/examples/todos/todos_appd/third_party/jquery-2.1.1.min.js b/examples/todos/todos_appd/third_party/jquery-2.1.1.min.js
deleted file mode 100644
index e5ace11..0000000
--- a/examples/todos/todos_appd/third_party/jquery-2.1.1.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
-!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)
-},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ib={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:"0",fontWeight:"400"},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?zb.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=yb(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(n.cssHooks[a+b].set=Gb)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}n.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Kb.prototype.init,n.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=n.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||tb(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?tb(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ub(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return n.map(k,Ub,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xb,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xb(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),n.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Lb=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Lb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Mb||(Mb=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Mb),Mb=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Yb,Zb,$b=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))
-},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||n.find.attr;$b[b]=function(a,b,d){var e,f;return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=n.now(),dc=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=l.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function tc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,n.ajaxSettings),b):tc(n.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Bc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Dc)Dc[a]()}),k.cors=!!Fc&&"withCredentials"in Fc,k.ajax=Fc=!!Fc,n.ajaxTransport(function(a){var b;return k.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Gc=[],Hc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Gc.pop()||n.expando+"_"+cc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Hc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Hc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Hc,"$1"+e):b.jsonp!==!1&&(b.url+=(dc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Gc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Ic=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Ic)return Ic.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Jc=a.document.documentElement;function Kc(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Kc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Jc;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Jc})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Kc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=yb(k.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Lc=a.jQuery,Mc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Mc),b&&a.jQuery===n&&(a.jQuery=Lc),n},typeof b===U&&(a.jQuery=a.$=n),n});
diff --git a/examples/todos/todos_appd/third_party/lodash.min.js b/examples/todos/todos_appd/third_party/lodash.min.js
deleted file mode 100644
index 85a9626..0000000
--- a/examples/todos/todos_appd/third_party/lodash.min.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @license
- * Lo-Dash 2.4.1 (Custom Build) lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE
- * Build: `lodash modern -o ./dist/lodash.js`
- */
-;(function(){function n(n,t,e){e=(e||0)-1;for(var r=n?n.length:0;++e<r;)if(n[e]===t)return e;return-1}function t(t,e){var r=typeof e;if(t=t.l,"boolean"==r||null==e)return t[e]?0:-1;"number"!=r&&"string"!=r&&(r="object");var u="number"==r?e:m+e;return t=(t=t[r])&&t[u],"object"==r?t&&-1<n(t,e)?0:-1:t?0:-1}function e(n){var t=this.l,e=typeof n;if("boolean"==e||null==n)t[n]=true;else{"number"!=e&&"string"!=e&&(e="object");var r="number"==e?n:m+n,t=t[e]||(t[e]={});"object"==e?(t[r]||(t[r]=[])).push(n):t[r]=true
-}}function r(n){return n.charCodeAt(0)}function u(n,t){for(var e=n.m,r=t.m,u=-1,o=e.length;++u<o;){var i=e[u],a=r[u];if(i!==a){if(i>a||typeof i=="undefined")return 1;if(i<a||typeof a=="undefined")return-1}}return n.n-t.n}function o(n){var t=-1,r=n.length,u=n[0],o=n[r/2|0],i=n[r-1];if(u&&typeof u=="object"&&o&&typeof o=="object"&&i&&typeof i=="object")return false;for(u=f(),u["false"]=u["null"]=u["true"]=u.undefined=false,o=f(),o.k=n,o.l=u,o.push=e;++t<r;)o.push(n[t]);return o}function i(n){return"\\"+U[n]
-}function a(){return h.pop()||[]}function f(){return g.pop()||{k:null,l:null,m:null,"false":false,n:0,"null":false,number:null,object:null,push:null,string:null,"true":false,undefined:false,o:null}}function l(n){n.length=0,h.length<_&&h.push(n)}function c(n){var t=n.l;t&&c(t),n.k=n.l=n.m=n.object=n.number=n.string=n.o=null,g.length<_&&g.push(n)}function p(n,t,e){t||(t=0),typeof e=="undefined"&&(e=n?n.length:0);var r=-1;e=e-t||0;for(var u=Array(0>e?0:e);++r<e;)u[r]=n[t+r];return u}function s(e){function h(n,t,e){if(!n||!V[typeof n])return n;
-t=t&&typeof e=="undefined"?t:tt(t,e,3);for(var r=-1,u=V[typeof n]&&Fe(n),o=u?u.length:0;++r<o&&(e=u[r],false!==t(n[e],e,n)););return n}function g(n,t,e){var r;if(!n||!V[typeof n])return n;t=t&&typeof e=="undefined"?t:tt(t,e,3);for(r in n)if(false===t(n[r],r,n))break;return n}function _(n,t,e){var r,u=n,o=u;if(!u)return o;for(var i=arguments,a=0,f=typeof e=="number"?2:i.length;++a<f;)if((u=i[a])&&V[typeof u])for(var l=-1,c=V[typeof u]&&Fe(u),p=c?c.length:0;++l<p;)r=c[l],"undefined"==typeof o[r]&&(o[r]=u[r]);
-return o}function U(n,t,e){var r,u=n,o=u;if(!u)return o;var i=arguments,a=0,f=typeof e=="number"?2:i.length;if(3<f&&"function"==typeof i[f-2])var l=tt(i[--f-1],i[f--],2);else 2<f&&"function"==typeof i[f-1]&&(l=i[--f]);for(;++a<f;)if((u=i[a])&&V[typeof u])for(var c=-1,p=V[typeof u]&&Fe(u),s=p?p.length:0;++c<s;)r=p[c],o[r]=l?l(o[r],u[r]):u[r];return o}function H(n){var t,e=[];if(!n||!V[typeof n])return e;for(t in n)me.call(n,t)&&e.push(t);return e}function J(n){return n&&typeof n=="object"&&!Te(n)&&me.call(n,"__wrapped__")?n:new Q(n)
-}function Q(n,t){this.__chain__=!!t,this.__wrapped__=n}function X(n){function t(){if(r){var n=p(r);be.apply(n,arguments)}if(this instanceof t){var o=nt(e.prototype),n=e.apply(o,n||arguments);return wt(n)?n:o}return e.apply(u,n||arguments)}var e=n[0],r=n[2],u=n[4];return $e(t,n),t}function Z(n,t,e,r,u){if(e){var o=e(n);if(typeof o!="undefined")return o}if(!wt(n))return n;var i=ce.call(n);if(!K[i])return n;var f=Ae[i];switch(i){case T:case F:return new f(+n);case W:case P:return new f(n);case z:return o=f(n.source,C.exec(n)),o.lastIndex=n.lastIndex,o
-}if(i=Te(n),t){var c=!r;r||(r=a()),u||(u=a());for(var s=r.length;s--;)if(r[s]==n)return u[s];o=i?f(n.length):{}}else o=i?p(n):U({},n);return i&&(me.call(n,"index")&&(o.index=n.index),me.call(n,"input")&&(o.input=n.input)),t?(r.push(n),u.push(o),(i?St:h)(n,function(n,i){o[i]=Z(n,t,e,r,u)}),c&&(l(r),l(u)),o):o}function nt(n){return wt(n)?ke(n):{}}function tt(n,t,e){if(typeof n!="function")return Ut;if(typeof t=="undefined"||!("prototype"in n))return n;var r=n.__bindData__;if(typeof r=="undefined"&&(De.funcNames&&(r=!n.name),r=r||!De.funcDecomp,!r)){var u=ge.call(n);
-De.funcNames||(r=!O.test(u)),r||(r=E.test(u),$e(n,r))}if(false===r||true!==r&&1&r[1])return n;switch(e){case 1:return function(e){return n.call(t,e)};case 2:return function(e,r){return n.call(t,e,r)};case 3:return function(e,r,u){return n.call(t,e,r,u)};case 4:return function(e,r,u,o){return n.call(t,e,r,u,o)}}return Mt(n,t)}function et(n){function t(){var n=f?i:this;if(u){var h=p(u);be.apply(h,arguments)}return(o||c)&&(h||(h=p(arguments)),o&&be.apply(h,o),c&&h.length<a)?(r|=16,et([e,s?r:-4&r,h,null,i,a])):(h||(h=arguments),l&&(e=n[v]),this instanceof t?(n=nt(e.prototype),h=e.apply(n,h),wt(h)?h:n):e.apply(n,h))
-}var e=n[0],r=n[1],u=n[2],o=n[3],i=n[4],a=n[5],f=1&r,l=2&r,c=4&r,s=8&r,v=e;return $e(t,n),t}function rt(e,r){var u=-1,i=st(),a=e?e.length:0,f=a>=b&&i===n,l=[];if(f){var p=o(r);p?(i=t,r=p):f=false}for(;++u<a;)p=e[u],0>i(r,p)&&l.push(p);return f&&c(r),l}function ut(n,t,e,r){r=(r||0)-1;for(var u=n?n.length:0,o=[];++r<u;){var i=n[r];if(i&&typeof i=="object"&&typeof i.length=="number"&&(Te(i)||yt(i))){t||(i=ut(i,t,e));var a=-1,f=i.length,l=o.length;for(o.length+=f;++a<f;)o[l++]=i[a]}else e||o.push(i)}return o
-}function ot(n,t,e,r,u,o){if(e){var i=e(n,t);if(typeof i!="undefined")return!!i}if(n===t)return 0!==n||1/n==1/t;if(n===n&&!(n&&V[typeof n]||t&&V[typeof t]))return false;if(null==n||null==t)return n===t;var f=ce.call(n),c=ce.call(t);if(f==D&&(f=q),c==D&&(c=q),f!=c)return false;switch(f){case T:case F:return+n==+t;case W:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case z:case P:return n==oe(t)}if(c=f==$,!c){var p=me.call(n,"__wrapped__"),s=me.call(t,"__wrapped__");if(p||s)return ot(p?n.__wrapped__:n,s?t.__wrapped__:t,e,r,u,o);
-if(f!=q)return false;if(f=n.constructor,p=t.constructor,f!=p&&!(dt(f)&&f instanceof f&&dt(p)&&p instanceof p)&&"constructor"in n&&"constructor"in t)return false}for(f=!u,u||(u=a()),o||(o=a()),p=u.length;p--;)if(u[p]==n)return o[p]==t;var v=0,i=true;if(u.push(n),o.push(t),c){if(p=n.length,v=t.length,(i=v==p)||r)for(;v--;)if(c=p,s=t[v],r)for(;c--&&!(i=ot(n[c],s,e,r,u,o)););else if(!(i=ot(n[v],s,e,r,u,o)))break}else g(t,function(t,a,f){return me.call(f,a)?(v++,i=me.call(n,a)&&ot(n[a],t,e,r,u,o)):void 0}),i&&!r&&g(n,function(n,t,e){return me.call(e,t)?i=-1<--v:void 0
-});return u.pop(),o.pop(),f&&(l(u),l(o)),i}function it(n,t,e,r,u){(Te(t)?St:h)(t,function(t,o){var i,a,f=t,l=n[o];if(t&&((a=Te(t))||Pe(t))){for(f=r.length;f--;)if(i=r[f]==t){l=u[f];break}if(!i){var c;e&&(f=e(l,t),c=typeof f!="undefined")&&(l=f),c||(l=a?Te(l)?l:[]:Pe(l)?l:{}),r.push(t),u.push(l),c||it(l,t,e,r,u)}}else e&&(f=e(l,t),typeof f=="undefined"&&(f=t)),typeof f!="undefined"&&(l=f);n[o]=l})}function at(n,t){return n+he(Re()*(t-n+1))}function ft(e,r,u){var i=-1,f=st(),p=e?e.length:0,s=[],v=!r&&p>=b&&f===n,h=u||v?a():s;
-for(v&&(h=o(h),f=t);++i<p;){var g=e[i],y=u?u(g,i,e):g;(r?!i||h[h.length-1]!==y:0>f(h,y))&&((u||v)&&h.push(y),s.push(g))}return v?(l(h.k),c(h)):u&&l(h),s}function lt(n){return function(t,e,r){var u={};e=J.createCallback(e,r,3),r=-1;var o=t?t.length:0;if(typeof o=="number")for(;++r<o;){var i=t[r];n(u,i,e(i,r,t),t)}else h(t,function(t,r,o){n(u,t,e(t,r,o),o)});return u}}function ct(n,t,e,r,u,o){var i=1&t,a=4&t,f=16&t,l=32&t;if(!(2&t||dt(n)))throw new ie;f&&!e.length&&(t&=-17,f=e=false),l&&!r.length&&(t&=-33,l=r=false);
-var c=n&&n.__bindData__;return c&&true!==c?(c=p(c),c[2]&&(c[2]=p(c[2])),c[3]&&(c[3]=p(c[3])),!i||1&c[1]||(c[4]=u),!i&&1&c[1]&&(t|=8),!a||4&c[1]||(c[5]=o),f&&be.apply(c[2]||(c[2]=[]),e),l&&we.apply(c[3]||(c[3]=[]),r),c[1]|=t,ct.apply(null,c)):(1==t||17===t?X:et)([n,t,e,r,u,o])}function pt(n){return Be[n]}function st(){var t=(t=J.indexOf)===Wt?n:t;return t}function vt(n){return typeof n=="function"&&pe.test(n)}function ht(n){var t,e;return n&&ce.call(n)==q&&(t=n.constructor,!dt(t)||t instanceof t)?(g(n,function(n,t){e=t
-}),typeof e=="undefined"||me.call(n,e)):false}function gt(n){return We[n]}function yt(n){return n&&typeof n=="object"&&typeof n.length=="number"&&ce.call(n)==D||false}function mt(n,t,e){var r=Fe(n),u=r.length;for(t=tt(t,e,3);u--&&(e=r[u],false!==t(n[e],e,n)););return n}function bt(n){var t=[];return g(n,function(n,e){dt(n)&&t.push(e)}),t.sort()}function _t(n){for(var t=-1,e=Fe(n),r=e.length,u={};++t<r;){var o=e[t];u[n[o]]=o}return u}function dt(n){return typeof n=="function"}function wt(n){return!(!n||!V[typeof n])
-}function jt(n){return typeof n=="number"||n&&typeof n=="object"&&ce.call(n)==W||false}function kt(n){return typeof n=="string"||n&&typeof n=="object"&&ce.call(n)==P||false}function xt(n){for(var t=-1,e=Fe(n),r=e.length,u=Xt(r);++t<r;)u[t]=n[e[t]];return u}function Ct(n,t,e){var r=-1,u=st(),o=n?n.length:0,i=false;return e=(0>e?Ie(0,o+e):e)||0,Te(n)?i=-1<u(n,t,e):typeof o=="number"?i=-1<(kt(n)?n.indexOf(t,e):u(n,t,e)):h(n,function(n){return++r<e?void 0:!(i=n===t)}),i}function Ot(n,t,e){var r=true;t=J.createCallback(t,e,3),e=-1;
-var u=n?n.length:0;if(typeof u=="number")for(;++e<u&&(r=!!t(n[e],e,n)););else h(n,function(n,e,u){return r=!!t(n,e,u)});return r}function Nt(n,t,e){var r=[];t=J.createCallback(t,e,3),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e<u;){var o=n[e];t(o,e,n)&&r.push(o)}else h(n,function(n,e,u){t(n,e,u)&&r.push(n)});return r}function It(n,t,e){t=J.createCallback(t,e,3),e=-1;var r=n?n.length:0;if(typeof r!="number"){var u;return h(n,function(n,e,r){return t(n,e,r)?(u=n,false):void 0}),u}for(;++e<r;){var o=n[e];
-if(t(o,e,n))return o}}function St(n,t,e){var r=-1,u=n?n.length:0;if(t=t&&typeof e=="undefined"?t:tt(t,e,3),typeof u=="number")for(;++r<u&&false!==t(n[r],r,n););else h(n,t);return n}function Et(n,t,e){var r=n?n.length:0;if(t=t&&typeof e=="undefined"?t:tt(t,e,3),typeof r=="number")for(;r--&&false!==t(n[r],r,n););else{var u=Fe(n),r=u.length;h(n,function(n,e,o){return e=u?u[--r]:--r,t(o[e],e,o)})}return n}function Rt(n,t,e){var r=-1,u=n?n.length:0;if(t=J.createCallback(t,e,3),typeof u=="number")for(var o=Xt(u);++r<u;)o[r]=t(n[r],r,n);
-else o=[],h(n,function(n,e,u){o[++r]=t(n,e,u)});return o}function At(n,t,e){var u=-1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&Te(n)){e=-1;for(var i=n.length;++e<i;){var a=n[e];a>o&&(o=a)}}else t=null==t&&kt(n)?r:J.createCallback(t,e,3),St(n,function(n,e,r){e=t(n,e,r),e>u&&(u=e,o=n)});return o}function Dt(n,t,e,r){if(!n)return e;var u=3>arguments.length;t=J.createCallback(t,r,4);var o=-1,i=n.length;if(typeof i=="number")for(u&&(e=n[++o]);++o<i;)e=t(e,n[o],o,n);else h(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)
-});return e}function $t(n,t,e,r){var u=3>arguments.length;return t=J.createCallback(t,r,4),Et(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)}),e}function Tt(n){var t=-1,e=n?n.length:0,r=Xt(typeof e=="number"?e:0);return St(n,function(n){var e=at(0,++t);r[t]=r[e],r[e]=n}),r}function Ft(n,t,e){var r;t=J.createCallback(t,e,3),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e<u&&!(r=t(n[e],e,n)););else h(n,function(n,e,u){return!(r=t(n,e,u))});return!!r}function Bt(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=-1;
-for(t=J.createCallback(t,e,3);++o<u&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n?n[0]:v;return p(n,0,Se(Ie(0,r),u))}function Wt(t,e,r){if(typeof r=="number"){var u=t?t.length:0;r=0>r?Ie(0,u+r):r||0}else if(r)return r=zt(t,e),t[r]===e?r:-1;return n(t,e,r)}function qt(n,t,e){if(typeof t!="number"&&null!=t){var r=0,u=-1,o=n?n.length:0;for(t=J.createCallback(t,e,3);++u<o&&t(n[u],u,n);)r++}else r=null==t||e?1:Ie(0,t);return p(n,r)}function zt(n,t,e,r){var u=0,o=n?n.length:u;for(e=e?J.createCallback(e,r,1):Ut,t=e(t);u<o;)r=u+o>>>1,e(n[r])<t?u=r+1:o=r;
-return u}function Pt(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(e=J.createCallback(e,r,3)),ft(n,t,e)}function Kt(){for(var n=1<arguments.length?arguments:arguments[0],t=-1,e=n?At(Ve(n,"length")):0,r=Xt(0>e?0:e);++t<e;)r[t]=Ve(n,t);return r}function Lt(n,t){var e=-1,r=n?n.length:0,u={};for(t||!r||Te(n[0])||(t=[]);++e<r;){var o=n[e];t?u[o]=t[e]:o&&(u[o[0]]=o[1])}return u}function Mt(n,t){return 2<arguments.length?ct(n,17,p(arguments,2),null,t):ct(n,1,null,null,t)
-}function Vt(n,t,e){function r(){c&&ve(c),i=c=p=v,(g||h!==t)&&(s=Ue(),a=n.apply(l,o),c||i||(o=l=null))}function u(){var e=t-(Ue()-f);0<e?c=_e(u,e):(i&&ve(i),e=p,i=c=p=v,e&&(s=Ue(),a=n.apply(l,o),c||i||(o=l=null)))}var o,i,a,f,l,c,p,s=0,h=false,g=true;if(!dt(n))throw new ie;if(t=Ie(0,t)||0,true===e)var y=true,g=false;else wt(e)&&(y=e.leading,h="maxWait"in e&&(Ie(t,e.maxWait)||0),g="trailing"in e?e.trailing:g);return function(){if(o=arguments,f=Ue(),l=this,p=g&&(c||!y),false===h)var e=y&&!c;else{i||y||(s=f);var v=h-(f-s),m=0>=v;
-m?(i&&(i=ve(i)),s=f,a=n.apply(l,o)):i||(i=_e(r,v))}return m&&c?c=ve(c):c||t===h||(c=_e(u,t)),e&&(m=true,a=n.apply(l,o)),!m||c||i||(o=l=null),a}}function Ut(n){return n}function Gt(n,t,e){var r=true,u=t&&bt(t);t&&(e||u.length)||(null==e&&(e=t),o=Q,t=n,n=J,u=bt(t)),false===e?r=false:wt(e)&&"chain"in e&&(r=e.chain);var o=n,i=dt(o);St(u,function(e){var u=n[e]=t[e];i&&(o.prototype[e]=function(){var t=this.__chain__,e=this.__wrapped__,i=[e];if(be.apply(i,arguments),i=u.apply(n,i),r||t){if(e===i&&wt(i))return this;
-i=new o(i),i.__chain__=t}return i})})}function Ht(){}function Jt(n){return function(t){return t[n]}}function Qt(){return this.__wrapped__}e=e?Y.defaults(G.Object(),e,Y.pick(G,A)):G;var Xt=e.Array,Yt=e.Boolean,Zt=e.Date,ne=e.Function,te=e.Math,ee=e.Number,re=e.Object,ue=e.RegExp,oe=e.String,ie=e.TypeError,ae=[],fe=re.prototype,le=e._,ce=fe.toString,pe=ue("^"+oe(ce).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),se=te.ceil,ve=e.clearTimeout,he=te.floor,ge=ne.prototype.toString,ye=vt(ye=re.getPrototypeOf)&&ye,me=fe.hasOwnProperty,be=ae.push,_e=e.setTimeout,de=ae.splice,we=ae.unshift,je=function(){try{var n={},t=vt(t=re.defineProperty)&&t,e=t(n,n,n)&&t
-}catch(r){}return e}(),ke=vt(ke=re.create)&&ke,xe=vt(xe=Xt.isArray)&&xe,Ce=e.isFinite,Oe=e.isNaN,Ne=vt(Ne=re.keys)&&Ne,Ie=te.max,Se=te.min,Ee=e.parseInt,Re=te.random,Ae={};Ae[$]=Xt,Ae[T]=Yt,Ae[F]=Zt,Ae[B]=ne,Ae[q]=re,Ae[W]=ee,Ae[z]=ue,Ae[P]=oe,Q.prototype=J.prototype;var De=J.support={};De.funcDecomp=!vt(e.a)&&E.test(s),De.funcNames=typeof ne.name=="string",J.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:N,variable:"",imports:{_:J}},ke||(nt=function(){function n(){}return function(t){if(wt(t)){n.prototype=t;
-var r=new n;n.prototype=null}return r||e.Object()}}());var $e=je?function(n,t){M.value=t,je(n,"__bindData__",M)}:Ht,Te=xe||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&ce.call(n)==$||false},Fe=Ne?function(n){return wt(n)?Ne(n):[]}:H,Be={"&":"&","<":"<",">":">",'"':""","'":"'"},We=_t(Be),qe=ue("("+Fe(We).join("|")+")","g"),ze=ue("["+Fe(Be).join("")+"]","g"),Pe=ye?function(n){if(!n||ce.call(n)!=q)return false;var t=n.valueOf,e=vt(t)&&(e=ye(t))&&ye(e);return e?n==e||ye(n)==e:ht(n)
-}:ht,Ke=lt(function(n,t,e){me.call(n,e)?n[e]++:n[e]=1}),Le=lt(function(n,t,e){(me.call(n,e)?n[e]:n[e]=[]).push(t)}),Me=lt(function(n,t,e){n[e]=t}),Ve=Rt,Ue=vt(Ue=Zt.now)&&Ue||function(){return(new Zt).getTime()},Ge=8==Ee(d+"08")?Ee:function(n,t){return Ee(kt(n)?n.replace(I,""):n,t||0)};return J.after=function(n,t){if(!dt(t))throw new ie;return function(){return 1>--n?t.apply(this,arguments):void 0}},J.assign=U,J.at=function(n){for(var t=arguments,e=-1,r=ut(t,true,false,1),t=t[2]&&t[2][t[1]]===n?1:r.length,u=Xt(t);++e<t;)u[e]=n[r[e]];
-return u},J.bind=Mt,J.bindAll=function(n){for(var t=1<arguments.length?ut(arguments,true,false,1):bt(n),e=-1,r=t.length;++e<r;){var u=t[e];n[u]=ct(n[u],1,null,null,n)}return n},J.bindKey=function(n,t){return 2<arguments.length?ct(t,19,p(arguments,2),null,n):ct(t,3,null,null,n)},J.chain=function(n){return n=new Q(n),n.__chain__=true,n},J.compact=function(n){for(var t=-1,e=n?n.length:0,r=[];++t<e;){var u=n[t];u&&r.push(u)}return r},J.compose=function(){for(var n=arguments,t=n.length;t--;)if(!dt(n[t]))throw new ie;
-return function(){for(var t=arguments,e=n.length;e--;)t=[n[e].apply(this,t)];return t[0]}},J.constant=function(n){return function(){return n}},J.countBy=Ke,J.create=function(n,t){var e=nt(n);return t?U(e,t):e},J.createCallback=function(n,t,e){var r=typeof n;if(null==n||"function"==r)return tt(n,t,e);if("object"!=r)return Jt(n);var u=Fe(n),o=u[0],i=n[o];return 1!=u.length||i!==i||wt(i)?function(t){for(var e=u.length,r=false;e--&&(r=ot(t[u[e]],n[u[e]],null,true)););return r}:function(n){return n=n[o],i===n&&(0!==i||1/i==1/n)
-}},J.curry=function(n,t){return t=typeof t=="number"?t:+t||n.length,ct(n,4,null,null,null,t)},J.debounce=Vt,J.defaults=_,J.defer=function(n){if(!dt(n))throw new ie;var t=p(arguments,1);return _e(function(){n.apply(v,t)},1)},J.delay=function(n,t){if(!dt(n))throw new ie;var e=p(arguments,2);return _e(function(){n.apply(v,e)},t)},J.difference=function(n){return rt(n,ut(arguments,true,true,1))},J.filter=Nt,J.flatten=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(n=Rt(n,e,r)),ut(n,t)
-},J.forEach=St,J.forEachRight=Et,J.forIn=g,J.forInRight=function(n,t,e){var r=[];g(n,function(n,t){r.push(t,n)});var u=r.length;for(t=tt(t,e,3);u--&&false!==t(r[u--],r[u],n););return n},J.forOwn=h,J.forOwnRight=mt,J.functions=bt,J.groupBy=Le,J.indexBy=Me,J.initial=function(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=u;for(t=J.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else r=null==t||e?1:t||r;return p(n,0,Se(Ie(0,u-r),u))},J.intersection=function(){for(var e=[],r=-1,u=arguments.length,i=a(),f=st(),p=f===n,s=a();++r<u;){var v=arguments[r];
-(Te(v)||yt(v))&&(e.push(v),i.push(p&&v.length>=b&&o(r?e[r]:s)))}var p=e[0],h=-1,g=p?p.length:0,y=[];n:for(;++h<g;){var m=i[0],v=p[h];if(0>(m?t(m,v):f(s,v))){for(r=u,(m||s).push(v);--r;)if(m=i[r],0>(m?t(m,v):f(e[r],v)))continue n;y.push(v)}}for(;u--;)(m=i[u])&&c(m);return l(i),l(s),y},J.invert=_t,J.invoke=function(n,t){var e=p(arguments,2),r=-1,u=typeof t=="function",o=n?n.length:0,i=Xt(typeof o=="number"?o:0);return St(n,function(n){i[++r]=(u?t:n[t]).apply(n,e)}),i},J.keys=Fe,J.map=Rt,J.mapValues=function(n,t,e){var r={};
-return t=J.createCallback(t,e,3),h(n,function(n,e,u){r[e]=t(n,e,u)}),r},J.max=At,J.memoize=function(n,t){function e(){var r=e.cache,u=t?t.apply(this,arguments):m+arguments[0];return me.call(r,u)?r[u]:r[u]=n.apply(this,arguments)}if(!dt(n))throw new ie;return e.cache={},e},J.merge=function(n){var t=arguments,e=2;if(!wt(n))return n;if("number"!=typeof t[2]&&(e=t.length),3<e&&"function"==typeof t[e-2])var r=tt(t[--e-1],t[e--],2);else 2<e&&"function"==typeof t[e-1]&&(r=t[--e]);for(var t=p(arguments,1,e),u=-1,o=a(),i=a();++u<e;)it(n,t[u],r,o,i);
-return l(o),l(i),n},J.min=function(n,t,e){var u=1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&Te(n)){e=-1;for(var i=n.length;++e<i;){var a=n[e];a<o&&(o=a)}}else t=null==t&&kt(n)?r:J.createCallback(t,e,3),St(n,function(n,e,r){e=t(n,e,r),e<u&&(u=e,o=n)});return o},J.omit=function(n,t,e){var r={};if(typeof t!="function"){var u=[];g(n,function(n,t){u.push(t)});for(var u=rt(u,ut(arguments,true,false,1)),o=-1,i=u.length;++o<i;){var a=u[o];r[a]=n[a]}}else t=J.createCallback(t,e,3),g(n,function(n,e,u){t(n,e,u)||(r[e]=n)
-});return r},J.once=function(n){var t,e;if(!dt(n))throw new ie;return function(){return t?e:(t=true,e=n.apply(this,arguments),n=null,e)}},J.pairs=function(n){for(var t=-1,e=Fe(n),r=e.length,u=Xt(r);++t<r;){var o=e[t];u[t]=[o,n[o]]}return u},J.partial=function(n){return ct(n,16,p(arguments,1))},J.partialRight=function(n){return ct(n,32,null,p(arguments,1))},J.pick=function(n,t,e){var r={};if(typeof t!="function")for(var u=-1,o=ut(arguments,true,false,1),i=wt(n)?o.length:0;++u<i;){var a=o[u];a in n&&(r[a]=n[a])
-}else t=J.createCallback(t,e,3),g(n,function(n,e,u){t(n,e,u)&&(r[e]=n)});return r},J.pluck=Ve,J.property=Jt,J.pull=function(n){for(var t=arguments,e=0,r=t.length,u=n?n.length:0;++e<r;)for(var o=-1,i=t[e];++o<u;)n[o]===i&&(de.call(n,o--,1),u--);return n},J.range=function(n,t,e){n=+n||0,e=typeof e=="number"?e:+e||1,null==t&&(t=n,n=0);var r=-1;t=Ie(0,se((t-n)/(e||1)));for(var u=Xt(t);++r<t;)u[r]=n,n+=e;return u},J.reject=function(n,t,e){return t=J.createCallback(t,e,3),Nt(n,function(n,e,r){return!t(n,e,r)
-})},J.remove=function(n,t,e){var r=-1,u=n?n.length:0,o=[];for(t=J.createCallback(t,e,3);++r<u;)e=n[r],t(e,r,n)&&(o.push(e),de.call(n,r--,1),u--);return o},J.rest=qt,J.shuffle=Tt,J.sortBy=function(n,t,e){var r=-1,o=Te(t),i=n?n.length:0,p=Xt(typeof i=="number"?i:0);for(o||(t=J.createCallback(t,e,3)),St(n,function(n,e,u){var i=p[++r]=f();o?i.m=Rt(t,function(t){return n[t]}):(i.m=a())[0]=t(n,e,u),i.n=r,i.o=n}),i=p.length,p.sort(u);i--;)n=p[i],p[i]=n.o,o||l(n.m),c(n);return p},J.tap=function(n,t){return t(n),n
-},J.throttle=function(n,t,e){var r=true,u=true;if(!dt(n))throw new ie;return false===e?r=false:wt(e)&&(r="leading"in e?e.leading:r,u="trailing"in e?e.trailing:u),L.leading=r,L.maxWait=t,L.trailing=u,Vt(n,t,L)},J.times=function(n,t,e){n=-1<(n=+n)?n:0;var r=-1,u=Xt(n);for(t=tt(t,e,1);++r<n;)u[r]=t(r);return u},J.toArray=function(n){return n&&typeof n.length=="number"?p(n):xt(n)},J.transform=function(n,t,e,r){var u=Te(n);if(null==e)if(u)e=[];else{var o=n&&n.constructor;e=nt(o&&o.prototype)}return t&&(t=J.createCallback(t,r,4),(u?St:h)(n,function(n,r,u){return t(e,n,r,u)
-})),e},J.union=function(){return ft(ut(arguments,true,true))},J.uniq=Pt,J.values=xt,J.where=Nt,J.without=function(n){return rt(n,p(arguments,1))},J.wrap=function(n,t){return ct(t,16,[n])},J.xor=function(){for(var n=-1,t=arguments.length;++n<t;){var e=arguments[n];if(Te(e)||yt(e))var r=r?ft(rt(r,e).concat(rt(e,r))):e}return r||[]},J.zip=Kt,J.zipObject=Lt,J.collect=Rt,J.drop=qt,J.each=St,J.eachRight=Et,J.extend=U,J.methods=bt,J.object=Lt,J.select=Nt,J.tail=qt,J.unique=Pt,J.unzip=Kt,Gt(J),J.clone=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=t,t=false),Z(n,t,typeof e=="function"&&tt(e,r,1))
-},J.cloneDeep=function(n,t,e){return Z(n,true,typeof t=="function"&&tt(t,e,1))},J.contains=Ct,J.escape=function(n){return null==n?"":oe(n).replace(ze,pt)},J.every=Ot,J.find=It,J.findIndex=function(n,t,e){var r=-1,u=n?n.length:0;for(t=J.createCallback(t,e,3);++r<u;)if(t(n[r],r,n))return r;return-1},J.findKey=function(n,t,e){var r;return t=J.createCallback(t,e,3),h(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},J.findLast=function(n,t,e){var r;return t=J.createCallback(t,e,3),Et(n,function(n,e,u){return t(n,e,u)?(r=n,false):void 0
-}),r},J.findLastIndex=function(n,t,e){var r=n?n.length:0;for(t=J.createCallback(t,e,3);r--;)if(t(n[r],r,n))return r;return-1},J.findLastKey=function(n,t,e){var r;return t=J.createCallback(t,e,3),mt(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},J.has=function(n,t){return n?me.call(n,t):false},J.identity=Ut,J.indexOf=Wt,J.isArguments=yt,J.isArray=Te,J.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&ce.call(n)==T||false},J.isDate=function(n){return n&&typeof n=="object"&&ce.call(n)==F||false
-},J.isElement=function(n){return n&&1===n.nodeType||false},J.isEmpty=function(n){var t=true;if(!n)return t;var e=ce.call(n),r=n.length;return e==$||e==P||e==D||e==q&&typeof r=="number"&&dt(n.splice)?!r:(h(n,function(){return t=false}),t)},J.isEqual=function(n,t,e,r){return ot(n,t,typeof e=="function"&&tt(e,r,2))},J.isFinite=function(n){return Ce(n)&&!Oe(parseFloat(n))},J.isFunction=dt,J.isNaN=function(n){return jt(n)&&n!=+n},J.isNull=function(n){return null===n},J.isNumber=jt,J.isObject=wt,J.isPlainObject=Pe,J.isRegExp=function(n){return n&&typeof n=="object"&&ce.call(n)==z||false
-},J.isString=kt,J.isUndefined=function(n){return typeof n=="undefined"},J.lastIndexOf=function(n,t,e){var r=n?n.length:0;for(typeof e=="number"&&(r=(0>e?Ie(0,r+e):Se(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},J.mixin=Gt,J.noConflict=function(){return e._=le,this},J.noop=Ht,J.now=Ue,J.parseInt=Ge,J.random=function(n,t,e){var r=null==n,u=null==t;return null==e&&(typeof n=="boolean"&&u?(e=n,n=1):u||typeof t!="boolean"||(e=t,u=true)),r&&u&&(t=1),n=+n||0,u?(t=n,n=0):t=+t||0,e||n%1||t%1?(e=Re(),Se(n+e*(t-n+parseFloat("1e-"+((e+"").length-1))),t)):at(n,t)
-},J.reduce=Dt,J.reduceRight=$t,J.result=function(n,t){if(n){var e=n[t];return dt(e)?n[t]():e}},J.runInContext=s,J.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:Fe(n).length},J.some=Ft,J.sortedIndex=zt,J.template=function(n,t,e){var r=J.templateSettings;n=oe(n||""),e=_({},e,r);var u,o=_({},e.imports,r.imports),r=Fe(o),o=xt(o),a=0,f=e.interpolate||S,l="__p+='",f=ue((e.escape||S).source+"|"+f.source+"|"+(f===N?x:S).source+"|"+(e.evaluate||S).source+"|$","g");n.replace(f,function(t,e,r,o,f,c){return r||(r=o),l+=n.slice(a,c).replace(R,i),e&&(l+="'+__e("+e+")+'"),f&&(u=true,l+="';"+f+";\n__p+='"),r&&(l+="'+((__t=("+r+"))==null?'':__t)+'"),a=c+t.length,t
-}),l+="';",f=e=e.variable,f||(e="obj",l="with("+e+"){"+l+"}"),l=(u?l.replace(w,""):l).replace(j,"$1").replace(k,"$1;"),l="function("+e+"){"+(f?"":e+"||("+e+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}";try{var c=ne(r,"return "+l).apply(v,o)}catch(p){throw p.source=l,p}return t?c(t):(c.source=l,c)},J.unescape=function(n){return null==n?"":oe(n).replace(qe,gt)},J.uniqueId=function(n){var t=++y;return oe(null==n?"":n)+t
-},J.all=Ot,J.any=Ft,J.detect=It,J.findWhere=It,J.foldl=Dt,J.foldr=$t,J.include=Ct,J.inject=Dt,Gt(function(){var n={};return h(J,function(t,e){J.prototype[e]||(n[e]=t)}),n}(),false),J.first=Bt,J.last=function(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=u;for(t=J.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n?n[u-1]:v;return p(n,Ie(0,u-r))},J.sample=function(n,t,e){return n&&typeof n.length!="number"&&(n=xt(n)),null==t||e?n?n[at(0,n.length-1)]:v:(n=Tt(n),n.length=Se(Ie(0,t),n.length),n)
-},J.take=Bt,J.head=Bt,h(J,function(n,t){var e="sample"!==t;J.prototype[t]||(J.prototype[t]=function(t,r){var u=this.__chain__,o=n(this.__wrapped__,t,r);return u||null!=t&&(!r||e&&typeof t=="function")?new Q(o,u):o})}),J.VERSION="2.4.1",J.prototype.chain=function(){return this.__chain__=true,this},J.prototype.toString=function(){return oe(this.__wrapped__)},J.prototype.value=Qt,J.prototype.valueOf=Qt,St(["join","pop","shift"],function(n){var t=ae[n];J.prototype[n]=function(){var n=this.__chain__,e=t.apply(this.__wrapped__,arguments);
-return n?new Q(e,n):e}}),St(["push","reverse","sort","unshift"],function(n){var t=ae[n];J.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),St(["concat","slice","splice"],function(n){var t=ae[n];J.prototype[n]=function(){return new Q(t.apply(this.__wrapped__,arguments),this.__chain__)}}),J}var v,h=[],g=[],y=0,m=+new Date+"",b=75,_=40,d=" \t\x0B\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",w=/\b__p\+='';/g,j=/\b(__p\+=)''\+/g,k=/(__e\(.*?\)|\b__t\))\+'';/g,x=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,C=/\w*$/,O=/^\s*function[ \n\r\t]+\w/,N=/<%=([\s\S]+?)%>/g,I=RegExp("^["+d+"]*0+(?=.$)"),S=/($^)/,E=/\bthis\b/,R=/['\n\r\t\u2028\u2029\\]/g,A="Array Boolean Date Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setTimeout".split(" "),D="[object Arguments]",$="[object Array]",T="[object Boolean]",F="[object Date]",B="[object Function]",W="[object Number]",q="[object Object]",z="[object RegExp]",P="[object String]",K={};
-K[B]=false,K[D]=K[$]=K[T]=K[F]=K[W]=K[q]=K[z]=K[P]=true;var L={leading:false,maxWait:0,trailing:false},M={configurable:false,enumerable:false,value:null,writable:false},V={"boolean":false,"function":true,object:true,number:false,string:false,undefined:false},U={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},G=V[typeof window]&&window||this,H=V[typeof exports]&&exports&&!exports.nodeType&&exports,J=V[typeof module]&&module&&!module.nodeType&&module,Q=J&&J.exports===H&&H,X=V[typeof global]&&global;!X||X.global!==X&&X.window!==X||(G=X);
-var Y=s();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(G._=Y, define(function(){return Y})):H&&J?Q?(J.exports=Y)._=Y:H._=Y:G._=Y}).call(this);
\ No newline at end of file
diff --git a/examples/todos/todos_appd/third_party/react-0.11.1.js b/examples/todos/todos_appd/third_party/react-0.11.1.js
deleted file mode 100644
index 57d5fe1..0000000
--- a/examples/todos/todos_appd/third_party/react-0.11.1.js
+++ /dev/null
@@ -1,18459 +0,0 @@
-/**
- * React v0.11.1
- */
-!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.React=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule AutoFocusMixin
- * @typechecks static-only
- */
-
-"use strict";
-
-var focusNode = _dereq_("./focusNode");
-
-var AutoFocusMixin = {
- componentDidMount: function() {
- if (this.props.autoFocus) {
- focusNode(this.getDOMNode());
- }
- }
-};
-
-module.exports = AutoFocusMixin;
-
-},{"./focusNode":106}],2:[function(_dereq_,module,exports){
-/**
- * Copyright 2013 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule BeforeInputEventPlugin
- * @typechecks static-only
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-var EventPropagators = _dereq_("./EventPropagators");
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-var SyntheticInputEvent = _dereq_("./SyntheticInputEvent");
-
-var keyOf = _dereq_("./keyOf");
-
-var canUseTextInputEvent = (
- ExecutionEnvironment.canUseDOM &&
- 'TextEvent' in window &&
- !('documentMode' in document || isPresto())
-);
-
-/**
- * Opera <= 12 includes TextEvent in window, but does not fire
- * text input events. Rely on keypress instead.
- */
-function isPresto() {
- var opera = window.opera;
- return (
- typeof opera === 'object' &&
- typeof opera.version === 'function' &&
- parseInt(opera.version(), 10) <= 12
- );
-}
-
-var SPACEBAR_CODE = 32;
-var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
-
-var topLevelTypes = EventConstants.topLevelTypes;
-
-// Events and their corresponding property names.
-var eventTypes = {
- beforeInput: {
- phasedRegistrationNames: {
- bubbled: keyOf({onBeforeInput: null}),
- captured: keyOf({onBeforeInputCapture: null})
- },
- dependencies: [
- topLevelTypes.topCompositionEnd,
- topLevelTypes.topKeyPress,
- topLevelTypes.topTextInput,
- topLevelTypes.topPaste
- ]
- }
-};
-
-// Track characters inserted via keypress and composition events.
-var fallbackChars = null;
-
-/**
- * Return whether a native keypress event is assumed to be a command.
- * This is required because Firefox fires `keypress` events for key commands
- * (cut, copy, select-all, etc.) even though no character is inserted.
- */
-function isKeypressCommand(nativeEvent) {
- return (
- (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
- // ctrlKey && altKey is equivalent to AltGr, and is not a command.
- !(nativeEvent.ctrlKey && nativeEvent.altKey)
- );
-}
-
-/**
- * Create an `onBeforeInput` event to match
- * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
- *
- * This event plugin is based on the native `textInput` event
- * available in Chrome, Safari, Opera, and IE. This event fires after
- * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
- *
- * `beforeInput` is spec'd but not implemented in any browsers, and
- * the `input` event does not provide any useful information about what has
- * actually been added, contrary to the spec. Thus, `textInput` is the best
- * available event to identify the characters that have actually been inserted
- * into the target node.
- */
-var BeforeInputEventPlugin = {
-
- eventTypes: eventTypes,
-
- /**
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {DOMEventTarget} topLevelTarget The listening component root node.
- * @param {string} topLevelTargetID ID of `topLevelTarget`.
- * @param {object} nativeEvent Native browser event.
- * @return {*} An accumulation of synthetic events.
- * @see {EventPluginHub.extractEvents}
- */
- extractEvents: function(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent) {
-
- var chars;
-
- if (canUseTextInputEvent) {
- switch (topLevelType) {
- case topLevelTypes.topKeyPress:
- /**
- * If native `textInput` events are available, our goal is to make
- * use of them. However, there is a special case: the spacebar key.
- * In Webkit, preventing default on a spacebar `textInput` event
- * cancels character insertion, but it *also* causes the browser
- * to fall back to its default spacebar behavior of scrolling the
- * page.
- *
- * Tracking at:
- * https://code.google.com/p/chromium/issues/detail?id=355103
- *
- * To avoid this issue, use the keypress event as if no `textInput`
- * event is available.
- */
- var which = nativeEvent.which;
- if (which !== SPACEBAR_CODE) {
- return;
- }
-
- chars = String.fromCharCode(which);
- break;
-
- case topLevelTypes.topTextInput:
- // Record the characters to be added to the DOM.
- chars = nativeEvent.data;
-
- // If it's a spacebar character, assume that we have already handled
- // it at the keypress level and bail immediately.
- if (chars === SPACEBAR_CHAR) {
- return;
- }
-
- // Otherwise, carry on.
- break;
-
- default:
- // For other native event types, do nothing.
- return;
- }
- } else {
- switch (topLevelType) {
- case topLevelTypes.topPaste:
- // If a paste event occurs after a keypress, throw out the input
- // chars. Paste events should not lead to BeforeInput events.
- fallbackChars = null;
- break;
- case topLevelTypes.topKeyPress:
- /**
- * As of v27, Firefox may fire keypress events even when no character
- * will be inserted. A few possibilities:
- *
- * - `which` is `0`. Arrow keys, Esc key, etc.
- *
- * - `which` is the pressed key code, but no char is available.
- * Ex: 'AltGr + d` in Polish. There is no modified character for
- * this key combination and no character is inserted into the
- * document, but FF fires the keypress for char code `100` anyway.
- * No `input` event will occur.
- *
- * - `which` is the pressed key code, but a command combination is
- * being used. Ex: `Cmd+C`. No character is inserted, and no
- * `input` event will occur.
- */
- if (nativeEvent.which && !isKeypressCommand(nativeEvent)) {
- fallbackChars = String.fromCharCode(nativeEvent.which);
- }
- break;
- case topLevelTypes.topCompositionEnd:
- fallbackChars = nativeEvent.data;
- break;
- }
-
- // If no changes have occurred to the fallback string, no relevant
- // event has fired and we're done.
- if (fallbackChars === null) {
- return;
- }
-
- chars = fallbackChars;
- }
-
- // If no characters are being inserted, no BeforeInput event should
- // be fired.
- if (!chars) {
- return;
- }
-
- var event = SyntheticInputEvent.getPooled(
- eventTypes.beforeInput,
- topLevelTargetID,
- nativeEvent
- );
-
- event.data = chars;
- fallbackChars = null;
- EventPropagators.accumulateTwoPhaseDispatches(event);
- return event;
- }
-};
-
-module.exports = BeforeInputEventPlugin;
-
-},{"./EventConstants":15,"./EventPropagators":20,"./ExecutionEnvironment":21,"./SyntheticInputEvent":86,"./keyOf":127}],3:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule CSSProperty
- */
-
-"use strict";
-
-/**
- * CSS properties which accept numbers but are not in units of "px".
- */
-var isUnitlessNumber = {
- columnCount: true,
- fillOpacity: true,
- flex: true,
- flexGrow: true,
- flexShrink: true,
- fontWeight: true,
- lineClamp: true,
- lineHeight: true,
- opacity: true,
- order: true,
- orphans: true,
- widows: true,
- zIndex: true,
- zoom: true
-};
-
-/**
- * @param {string} prefix vendor-specific prefix, eg: Webkit
- * @param {string} key style name, eg: transitionDuration
- * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
- * WebkitTransitionDuration
- */
-function prefixKey(prefix, key) {
- return prefix + key.charAt(0).toUpperCase() + key.substring(1);
-}
-
-/**
- * Support style names that may come passed in prefixed by adding permutations
- * of vendor prefixes.
- */
-var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
-
-// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
-// infinite loop, because it iterates over the newly added props too.
-Object.keys(isUnitlessNumber).forEach(function(prop) {
- prefixes.forEach(function(prefix) {
- isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
- });
-});
-
-/**
- * Most style properties can be unset by doing .style[prop] = '' but IE8
- * doesn't like doing that with shorthand properties so for the properties that
- * IE8 breaks on, which are listed here, we instead unset each of the
- * individual properties. See http://bugs.jquery.com/ticket/12385.
- * The 4-value 'clock' properties like margin, padding, border-width seem to
- * behave without any problems. Curiously, list-style works too without any
- * special prodding.
- */
-var shorthandPropertyExpansions = {
- background: {
- backgroundImage: true,
- backgroundPosition: true,
- backgroundRepeat: true,
- backgroundColor: true
- },
- border: {
- borderWidth: true,
- borderStyle: true,
- borderColor: true
- },
- borderBottom: {
- borderBottomWidth: true,
- borderBottomStyle: true,
- borderBottomColor: true
- },
- borderLeft: {
- borderLeftWidth: true,
- borderLeftStyle: true,
- borderLeftColor: true
- },
- borderRight: {
- borderRightWidth: true,
- borderRightStyle: true,
- borderRightColor: true
- },
- borderTop: {
- borderTopWidth: true,
- borderTopStyle: true,
- borderTopColor: true
- },
- font: {
- fontStyle: true,
- fontVariant: true,
- fontWeight: true,
- fontSize: true,
- lineHeight: true,
- fontFamily: true
- }
-};
-
-var CSSProperty = {
- isUnitlessNumber: isUnitlessNumber,
- shorthandPropertyExpansions: shorthandPropertyExpansions
-};
-
-module.exports = CSSProperty;
-
-},{}],4:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule CSSPropertyOperations
- * @typechecks static-only
- */
-
-"use strict";
-
-var CSSProperty = _dereq_("./CSSProperty");
-
-var dangerousStyleValue = _dereq_("./dangerousStyleValue");
-var hyphenateStyleName = _dereq_("./hyphenateStyleName");
-var memoizeStringOnly = _dereq_("./memoizeStringOnly");
-
-var processStyleName = memoizeStringOnly(function(styleName) {
- return hyphenateStyleName(styleName);
-});
-
-/**
- * Operations for dealing with CSS properties.
- */
-var CSSPropertyOperations = {
-
- /**
- * Serializes a mapping of style properties for use as inline styles:
- *
- * > createMarkupForStyles({width: '200px', height: 0})
- * "width:200px;height:0;"
- *
- * Undefined values are ignored so that declarative programming is easier.
- * The result should be HTML-escaped before insertion into the DOM.
- *
- * @param {object} styles
- * @return {?string}
- */
- createMarkupForStyles: function(styles) {
- var serialized = '';
- for (var styleName in styles) {
- if (!styles.hasOwnProperty(styleName)) {
- continue;
- }
- var styleValue = styles[styleName];
- if (styleValue != null) {
- serialized += processStyleName(styleName) + ':';
- serialized += dangerousStyleValue(styleName, styleValue) + ';';
- }
- }
- return serialized || null;
- },
-
- /**
- * Sets the value for multiple styles on a node. If a value is specified as
- * '' (empty string), the corresponding style property will be unset.
- *
- * @param {DOMElement} node
- * @param {object} styles
- */
- setValueForStyles: function(node, styles) {
- var style = node.style;
- for (var styleName in styles) {
- if (!styles.hasOwnProperty(styleName)) {
- continue;
- }
- var styleValue = dangerousStyleValue(styleName, styles[styleName]);
- if (styleValue) {
- style[styleName] = styleValue;
- } else {
- var expansion = CSSProperty.shorthandPropertyExpansions[styleName];
- if (expansion) {
- // Shorthand property that IE8 won't like unsetting, so unset each
- // component to placate it
- for (var individualStyleName in expansion) {
- style[individualStyleName] = '';
- }
- } else {
- style[styleName] = '';
- }
- }
- }
- }
-
-};
-
-module.exports = CSSPropertyOperations;
-
-},{"./CSSProperty":3,"./dangerousStyleValue":101,"./hyphenateStyleName":118,"./memoizeStringOnly":129}],5:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule CallbackQueue
- */
-
-"use strict";
-
-var PooledClass = _dereq_("./PooledClass");
-
-var invariant = _dereq_("./invariant");
-var mixInto = _dereq_("./mixInto");
-
-/**
- * A specialized pseudo-event module to help keep track of components waiting to
- * be notified when their DOM representations are available for use.
- *
- * This implements `PooledClass`, so you should never need to instantiate this.
- * Instead, use `CallbackQueue.getPooled()`.
- *
- * @class ReactMountReady
- * @implements PooledClass
- * @internal
- */
-function CallbackQueue() {
- this._callbacks = null;
- this._contexts = null;
-}
-
-mixInto(CallbackQueue, {
-
- /**
- * Enqueues a callback to be invoked when `notifyAll` is invoked.
- *
- * @param {function} callback Invoked when `notifyAll` is invoked.
- * @param {?object} context Context to call `callback` with.
- * @internal
- */
- enqueue: function(callback, context) {
- this._callbacks = this._callbacks || [];
- this._contexts = this._contexts || [];
- this._callbacks.push(callback);
- this._contexts.push(context);
- },
-
- /**
- * Invokes all enqueued callbacks and clears the queue. This is invoked after
- * the DOM representation of a component has been created or updated.
- *
- * @internal
- */
- notifyAll: function() {
- var callbacks = this._callbacks;
- var contexts = this._contexts;
- if (callbacks) {
- ("production" !== "development" ? invariant(
- callbacks.length === contexts.length,
- "Mismatched list of contexts in callback queue"
- ) : invariant(callbacks.length === contexts.length));
- this._callbacks = null;
- this._contexts = null;
- for (var i = 0, l = callbacks.length; i < l; i++) {
- callbacks[i].call(contexts[i]);
- }
- callbacks.length = 0;
- contexts.length = 0;
- }
- },
-
- /**
- * Resets the internal queue.
- *
- * @internal
- */
- reset: function() {
- this._callbacks = null;
- this._contexts = null;
- },
-
- /**
- * `PooledClass` looks for this.
- */
- destructor: function() {
- this.reset();
- }
-
-});
-
-PooledClass.addPoolingTo(CallbackQueue);
-
-module.exports = CallbackQueue;
-
-},{"./PooledClass":26,"./invariant":120,"./mixInto":133}],6:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ChangeEventPlugin
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-var EventPluginHub = _dereq_("./EventPluginHub");
-var EventPropagators = _dereq_("./EventPropagators");
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-var ReactUpdates = _dereq_("./ReactUpdates");
-var SyntheticEvent = _dereq_("./SyntheticEvent");
-
-var isEventSupported = _dereq_("./isEventSupported");
-var isTextInputElement = _dereq_("./isTextInputElement");
-var keyOf = _dereq_("./keyOf");
-
-var topLevelTypes = EventConstants.topLevelTypes;
-
-var eventTypes = {
- change: {
- phasedRegistrationNames: {
- bubbled: keyOf({onChange: null}),
- captured: keyOf({onChangeCapture: null})
- },
- dependencies: [
- topLevelTypes.topBlur,
- topLevelTypes.topChange,
- topLevelTypes.topClick,
- topLevelTypes.topFocus,
- topLevelTypes.topInput,
- topLevelTypes.topKeyDown,
- topLevelTypes.topKeyUp,
- topLevelTypes.topSelectionChange
- ]
- }
-};
-
-/**
- * For IE shims
- */
-var activeElement = null;
-var activeElementID = null;
-var activeElementValue = null;
-var activeElementValueProp = null;
-
-/**
- * SECTION: handle `change` event
- */
-function shouldUseChangeEvent(elem) {
- return (
- elem.nodeName === 'SELECT' ||
- (elem.nodeName === 'INPUT' && elem.type === 'file')
- );
-}
-
-var doesChangeEventBubble = false;
-if (ExecutionEnvironment.canUseDOM) {
- // See `handleChange` comment below
- doesChangeEventBubble = isEventSupported('change') && (
- !('documentMode' in document) || document.documentMode > 8
- );
-}
-
-function manualDispatchChangeEvent(nativeEvent) {
- var event = SyntheticEvent.getPooled(
- eventTypes.change,
- activeElementID,
- nativeEvent
- );
- EventPropagators.accumulateTwoPhaseDispatches(event);
-
- // If change and propertychange bubbled, we'd just bind to it like all the
- // other events and have it go through ReactBrowserEventEmitter. Since it
- // doesn't, we manually listen for the events and so we have to enqueue and
- // process the abstract event manually.
- //
- // Batching is necessary here in order to ensure that all event handlers run
- // before the next rerender (including event handlers attached to ancestor
- // elements instead of directly on the input). Without this, controlled
- // components don't work properly in conjunction with event bubbling because
- // the component is rerendered and the value reverted before all the event
- // handlers can run. See https://github.com/facebook/react/issues/708.
- ReactUpdates.batchedUpdates(runEventInBatch, event);
-}
-
-function runEventInBatch(event) {
- EventPluginHub.enqueueEvents(event);
- EventPluginHub.processEventQueue();
-}
-
-function startWatchingForChangeEventIE8(target, targetID) {
- activeElement = target;
- activeElementID = targetID;
- activeElement.attachEvent('onchange', manualDispatchChangeEvent);
-}
-
-function stopWatchingForChangeEventIE8() {
- if (!activeElement) {
- return;
- }
- activeElement.detachEvent('onchange', manualDispatchChangeEvent);
- activeElement = null;
- activeElementID = null;
-}
-
-function getTargetIDForChangeEvent(
- topLevelType,
- topLevelTarget,
- topLevelTargetID) {
- if (topLevelType === topLevelTypes.topChange) {
- return topLevelTargetID;
- }
-}
-function handleEventsForChangeEventIE8(
- topLevelType,
- topLevelTarget,
- topLevelTargetID) {
- if (topLevelType === topLevelTypes.topFocus) {
- // stopWatching() should be a noop here but we call it just in case we
- // missed a blur event somehow.
- stopWatchingForChangeEventIE8();
- startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID);
- } else if (topLevelType === topLevelTypes.topBlur) {
- stopWatchingForChangeEventIE8();
- }
-}
-
-
-/**
- * SECTION: handle `input` event
- */
-var isInputEventSupported = false;
-if (ExecutionEnvironment.canUseDOM) {
- // IE9 claims to support the input event but fails to trigger it when
- // deleting text, so we ignore its input events
- isInputEventSupported = isEventSupported('input') && (
- !('documentMode' in document) || document.documentMode > 9
- );
-}
-
-/**
- * (For old IE.) Replacement getter/setter for the `value` property that gets
- * set on the active element.
- */
-var newValueProp = {
- get: function() {
- return activeElementValueProp.get.call(this);
- },
- set: function(val) {
- // Cast to a string so we can do equality checks.
- activeElementValue = '' + val;
- activeElementValueProp.set.call(this, val);
- }
-};
-
-/**
- * (For old IE.) Starts tracking propertychange events on the passed-in element
- * and override the value property so that we can distinguish user events from
- * value changes in JS.
- */
-function startWatchingForValueChange(target, targetID) {
- activeElement = target;
- activeElementID = targetID;
- activeElementValue = target.value;
- activeElementValueProp = Object.getOwnPropertyDescriptor(
- target.constructor.prototype,
- 'value'
- );
-
- Object.defineProperty(activeElement, 'value', newValueProp);
- activeElement.attachEvent('onpropertychange', handlePropertyChange);
-}
-
-/**
- * (For old IE.) Removes the event listeners from the currently-tracked element,
- * if any exists.
- */
-function stopWatchingForValueChange() {
- if (!activeElement) {
- return;
- }
-
- // delete restores the original property definition
- delete activeElement.value;
- activeElement.detachEvent('onpropertychange', handlePropertyChange);
-
- activeElement = null;
- activeElementID = null;
- activeElementValue = null;
- activeElementValueProp = null;
-}
-
-/**
- * (For old IE.) Handles a propertychange event, sending a `change` event if
- * the value of the active element has changed.
- */
-function handlePropertyChange(nativeEvent) {
- if (nativeEvent.propertyName !== 'value') {
- return;
- }
- var value = nativeEvent.srcElement.value;
- if (value === activeElementValue) {
- return;
- }
- activeElementValue = value;
-
- manualDispatchChangeEvent(nativeEvent);
-}
-
-/**
- * If a `change` event should be fired, returns the target's ID.
- */
-function getTargetIDForInputEvent(
- topLevelType,
- topLevelTarget,
- topLevelTargetID) {
- if (topLevelType === topLevelTypes.topInput) {
- // In modern browsers (i.e., not IE8 or IE9), the input event is exactly
- // what we want so fall through here and trigger an abstract event
- return topLevelTargetID;
- }
-}
-
-// For IE8 and IE9.
-function handleEventsForInputEventIE(
- topLevelType,
- topLevelTarget,
- topLevelTargetID) {
- if (topLevelType === topLevelTypes.topFocus) {
- // In IE8, we can capture almost all .value changes by adding a
- // propertychange handler and looking for events with propertyName
- // equal to 'value'
- // In IE9, propertychange fires for most input events but is buggy and
- // doesn't fire when text is deleted, but conveniently, selectionchange
- // appears to fire in all of the remaining cases so we catch those and
- // forward the event if the value has changed
- // In either case, we don't want to call the event handler if the value
- // is changed from JS so we redefine a setter for `.value` that updates
- // our activeElementValue variable, allowing us to ignore those changes
- //
- // stopWatching() should be a noop here but we call it just in case we
- // missed a blur event somehow.
- stopWatchingForValueChange();
- startWatchingForValueChange(topLevelTarget, topLevelTargetID);
- } else if (topLevelType === topLevelTypes.topBlur) {
- stopWatchingForValueChange();
- }
-}
-
-// For IE8 and IE9.
-function getTargetIDForInputEventIE(
- topLevelType,
- topLevelTarget,
- topLevelTargetID) {
- if (topLevelType === topLevelTypes.topSelectionChange ||
- topLevelType === topLevelTypes.topKeyUp ||
- topLevelType === topLevelTypes.topKeyDown) {
- // On the selectionchange event, the target is just document which isn't
- // helpful for us so just check activeElement instead.
- //
- // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
- // propertychange on the first input event after setting `value` from a
- // script and fires only keydown, keypress, keyup. Catching keyup usually
- // gets it and catching keydown lets us fire an event for the first
- // keystroke if user does a key repeat (it'll be a little delayed: right
- // before the second keystroke). Other input methods (e.g., paste) seem to
- // fire selectionchange normally.
- if (activeElement && activeElement.value !== activeElementValue) {
- activeElementValue = activeElement.value;
- return activeElementID;
- }
- }
-}
-
-
-/**
- * SECTION: handle `click` event
- */
-function shouldUseClickEvent(elem) {
- // Use the `click` event to detect changes to checkbox and radio inputs.
- // This approach works across all browsers, whereas `change` does not fire
- // until `blur` in IE8.
- return (
- elem.nodeName === 'INPUT' &&
- (elem.type === 'checkbox' || elem.type === 'radio')
- );
-}
-
-function getTargetIDForClickEvent(
- topLevelType,
- topLevelTarget,
- topLevelTargetID) {
- if (topLevelType === topLevelTypes.topClick) {
- return topLevelTargetID;
- }
-}
-
-/**
- * This plugin creates an `onChange` event that normalizes change events
- * across form elements. This event fires at a time when it's possible to
- * change the element's value without seeing a flicker.
- *
- * Supported elements are:
- * - input (see `isTextInputElement`)
- * - textarea
- * - select
- */
-var ChangeEventPlugin = {
-
- eventTypes: eventTypes,
-
- /**
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {DOMEventTarget} topLevelTarget The listening component root node.
- * @param {string} topLevelTargetID ID of `topLevelTarget`.
- * @param {object} nativeEvent Native browser event.
- * @return {*} An accumulation of synthetic events.
- * @see {EventPluginHub.extractEvents}
- */
- extractEvents: function(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent) {
-
- var getTargetIDFunc, handleEventFunc;
- if (shouldUseChangeEvent(topLevelTarget)) {
- if (doesChangeEventBubble) {
- getTargetIDFunc = getTargetIDForChangeEvent;
- } else {
- handleEventFunc = handleEventsForChangeEventIE8;
- }
- } else if (isTextInputElement(topLevelTarget)) {
- if (isInputEventSupported) {
- getTargetIDFunc = getTargetIDForInputEvent;
- } else {
- getTargetIDFunc = getTargetIDForInputEventIE;
- handleEventFunc = handleEventsForInputEventIE;
- }
- } else if (shouldUseClickEvent(topLevelTarget)) {
- getTargetIDFunc = getTargetIDForClickEvent;
- }
-
- if (getTargetIDFunc) {
- var targetID = getTargetIDFunc(
- topLevelType,
- topLevelTarget,
- topLevelTargetID
- );
- if (targetID) {
- var event = SyntheticEvent.getPooled(
- eventTypes.change,
- targetID,
- nativeEvent
- );
- EventPropagators.accumulateTwoPhaseDispatches(event);
- return event;
- }
- }
-
- if (handleEventFunc) {
- handleEventFunc(
- topLevelType,
- topLevelTarget,
- topLevelTargetID
- );
- }
- }
-
-};
-
-module.exports = ChangeEventPlugin;
-
-},{"./EventConstants":15,"./EventPluginHub":17,"./EventPropagators":20,"./ExecutionEnvironment":21,"./ReactUpdates":76,"./SyntheticEvent":84,"./isEventSupported":121,"./isTextInputElement":123,"./keyOf":127}],7:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ClientReactRootIndex
- * @typechecks
- */
-
-"use strict";
-
-var nextReactRootIndex = 0;
-
-var ClientReactRootIndex = {
- createReactRootIndex: function() {
- return nextReactRootIndex++;
- }
-};
-
-module.exports = ClientReactRootIndex;
-
-},{}],8:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule CompositionEventPlugin
- * @typechecks static-only
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-var EventPropagators = _dereq_("./EventPropagators");
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-var ReactInputSelection = _dereq_("./ReactInputSelection");
-var SyntheticCompositionEvent = _dereq_("./SyntheticCompositionEvent");
-
-var getTextContentAccessor = _dereq_("./getTextContentAccessor");
-var keyOf = _dereq_("./keyOf");
-
-var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
-var START_KEYCODE = 229;
-
-var useCompositionEvent = (
- ExecutionEnvironment.canUseDOM &&
- 'CompositionEvent' in window
-);
-
-// In IE9+, we have access to composition events, but the data supplied
-// by the native compositionend event may be incorrect. In Korean, for example,
-// the compositionend event contains only one character regardless of
-// how many characters have been composed since compositionstart.
-// We therefore use the fallback data while still using the native
-// events as triggers.
-var useFallbackData = (
- !useCompositionEvent ||
- (
- 'documentMode' in document &&
- document.documentMode > 8 &&
- document.documentMode <= 11
- )
-);
-
-var topLevelTypes = EventConstants.topLevelTypes;
-var currentComposition = null;
-
-// Events and their corresponding property names.
-var eventTypes = {
- compositionEnd: {
- phasedRegistrationNames: {
- bubbled: keyOf({onCompositionEnd: null}),
- captured: keyOf({onCompositionEndCapture: null})
- },
- dependencies: [
- topLevelTypes.topBlur,
- topLevelTypes.topCompositionEnd,
- topLevelTypes.topKeyDown,
- topLevelTypes.topKeyPress,
- topLevelTypes.topKeyUp,
- topLevelTypes.topMouseDown
- ]
- },
- compositionStart: {
- phasedRegistrationNames: {
- bubbled: keyOf({onCompositionStart: null}),
- captured: keyOf({onCompositionStartCapture: null})
- },
- dependencies: [
- topLevelTypes.topBlur,
- topLevelTypes.topCompositionStart,
- topLevelTypes.topKeyDown,
- topLevelTypes.topKeyPress,
- topLevelTypes.topKeyUp,
- topLevelTypes.topMouseDown
- ]
- },
- compositionUpdate: {
- phasedRegistrationNames: {
- bubbled: keyOf({onCompositionUpdate: null}),
- captured: keyOf({onCompositionUpdateCapture: null})
- },
- dependencies: [
- topLevelTypes.topBlur,
- topLevelTypes.topCompositionUpdate,
- topLevelTypes.topKeyDown,
- topLevelTypes.topKeyPress,
- topLevelTypes.topKeyUp,
- topLevelTypes.topMouseDown
- ]
- }
-};
-
-/**
- * Translate native top level events into event types.
- *
- * @param {string} topLevelType
- * @return {object}
- */
-function getCompositionEventType(topLevelType) {
- switch (topLevelType) {
- case topLevelTypes.topCompositionStart:
- return eventTypes.compositionStart;
- case topLevelTypes.topCompositionEnd:
- return eventTypes.compositionEnd;
- case topLevelTypes.topCompositionUpdate:
- return eventTypes.compositionUpdate;
- }
-}
-
-/**
- * Does our fallback best-guess model think this event signifies that
- * composition has begun?
- *
- * @param {string} topLevelType
- * @param {object} nativeEvent
- * @return {boolean}
- */
-function isFallbackStart(topLevelType, nativeEvent) {
- return (
- topLevelType === topLevelTypes.topKeyDown &&
- nativeEvent.keyCode === START_KEYCODE
- );
-}
-
-/**
- * Does our fallback mode think that this event is the end of composition?
- *
- * @param {string} topLevelType
- * @param {object} nativeEvent
- * @return {boolean}
- */
-function isFallbackEnd(topLevelType, nativeEvent) {
- switch (topLevelType) {
- case topLevelTypes.topKeyUp:
- // Command keys insert or clear IME input.
- return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1);
- case topLevelTypes.topKeyDown:
- // Expect IME keyCode on each keydown. If we get any other
- // code we must have exited earlier.
- return (nativeEvent.keyCode !== START_KEYCODE);
- case topLevelTypes.topKeyPress:
- case topLevelTypes.topMouseDown:
- case topLevelTypes.topBlur:
- // Events are not possible without cancelling IME.
- return true;
- default:
- return false;
- }
-}
-
-/**
- * Helper class stores information about selection and document state
- * so we can figure out what changed at a later date.
- *
- * @param {DOMEventTarget} root
- */
-function FallbackCompositionState(root) {
- this.root = root;
- this.startSelection = ReactInputSelection.getSelection(root);
- this.startValue = this.getText();
-}
-
-/**
- * Get current text of input.
- *
- * @return {string}
- */
-FallbackCompositionState.prototype.getText = function() {
- return this.root.value || this.root[getTextContentAccessor()];
-};
-
-/**
- * Text that has changed since the start of composition.
- *
- * @return {string}
- */
-FallbackCompositionState.prototype.getData = function() {
- var endValue = this.getText();
- var prefixLength = this.startSelection.start;
- var suffixLength = this.startValue.length - this.startSelection.end;
-
- return endValue.substr(
- prefixLength,
- endValue.length - suffixLength - prefixLength
- );
-};
-
-/**
- * This plugin creates `onCompositionStart`, `onCompositionUpdate` and
- * `onCompositionEnd` events on inputs, textareas and contentEditable
- * nodes.
- */
-var CompositionEventPlugin = {
-
- eventTypes: eventTypes,
-
- /**
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {DOMEventTarget} topLevelTarget The listening component root node.
- * @param {string} topLevelTargetID ID of `topLevelTarget`.
- * @param {object} nativeEvent Native browser event.
- * @return {*} An accumulation of synthetic events.
- * @see {EventPluginHub.extractEvents}
- */
- extractEvents: function(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent) {
-
- var eventType;
- var data;
-
- if (useCompositionEvent) {
- eventType = getCompositionEventType(topLevelType);
- } else if (!currentComposition) {
- if (isFallbackStart(topLevelType, nativeEvent)) {
- eventType = eventTypes.compositionStart;
- }
- } else if (isFallbackEnd(topLevelType, nativeEvent)) {
- eventType = eventTypes.compositionEnd;
- }
-
- if (useFallbackData) {
- // The current composition is stored statically and must not be
- // overwritten while composition continues.
- if (!currentComposition && eventType === eventTypes.compositionStart) {
- currentComposition = new FallbackCompositionState(topLevelTarget);
- } else if (eventType === eventTypes.compositionEnd) {
- if (currentComposition) {
- data = currentComposition.getData();
- currentComposition = null;
- }
- }
- }
-
- if (eventType) {
- var event = SyntheticCompositionEvent.getPooled(
- eventType,
- topLevelTargetID,
- nativeEvent
- );
- if (data) {
- // Inject data generated from fallback path into the synthetic event.
- // This matches the property of native CompositionEventInterface.
- event.data = data;
- }
- EventPropagators.accumulateTwoPhaseDispatches(event);
- return event;
- }
- }
-};
-
-module.exports = CompositionEventPlugin;
-
-},{"./EventConstants":15,"./EventPropagators":20,"./ExecutionEnvironment":21,"./ReactInputSelection":58,"./SyntheticCompositionEvent":82,"./getTextContentAccessor":115,"./keyOf":127}],9:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule DOMChildrenOperations
- * @typechecks static-only
- */
-
-"use strict";
-
-var Danger = _dereq_("./Danger");
-var ReactMultiChildUpdateTypes = _dereq_("./ReactMultiChildUpdateTypes");
-
-var getTextContentAccessor = _dereq_("./getTextContentAccessor");
-var invariant = _dereq_("./invariant");
-
-/**
- * The DOM property to use when setting text content.
- *
- * @type {string}
- * @private
- */
-var textContentAccessor = getTextContentAccessor();
-
-/**
- * Inserts `childNode` as a child of `parentNode` at the `index`.
- *
- * @param {DOMElement} parentNode Parent node in which to insert.
- * @param {DOMElement} childNode Child node to insert.
- * @param {number} index Index at which to insert the child.
- * @internal
- */
-function insertChildAt(parentNode, childNode, index) {
- // By exploiting arrays returning `undefined` for an undefined index, we can
- // rely exclusively on `insertBefore(node, null)` instead of also using
- // `appendChild(node)`. However, using `undefined` is not allowed by all
- // browsers so we must replace it with `null`.
- parentNode.insertBefore(
- childNode,
- parentNode.childNodes[index] || null
- );
-}
-
-var updateTextContent;
-if (textContentAccessor === 'textContent') {
- /**
- * Sets the text content of `node` to `text`.
- *
- * @param {DOMElement} node Node to change
- * @param {string} text New text content
- */
- updateTextContent = function(node, text) {
- node.textContent = text;
- };
-} else {
- /**
- * Sets the text content of `node` to `text`.
- *
- * @param {DOMElement} node Node to change
- * @param {string} text New text content
- */
- updateTextContent = function(node, text) {
- // In order to preserve newlines correctly, we can't use .innerText to set
- // the contents (see #1080), so we empty the element then append a text node
- while (node.firstChild) {
- node.removeChild(node.firstChild);
- }
- if (text) {
- var doc = node.ownerDocument || document;
- node.appendChild(doc.createTextNode(text));
- }
- };
-}
-
-/**
- * Operations for updating with DOM children.
- */
-var DOMChildrenOperations = {
-
- dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup,
-
- updateTextContent: updateTextContent,
-
- /**
- * Updates a component's children by processing a series of updates. The
- * update configurations are each expected to have a `parentNode` property.
- *
- * @param {array<object>} updates List of update configurations.
- * @param {array<string>} markupList List of markup strings.
- * @internal
- */
- processUpdates: function(updates, markupList) {
- var update;
- // Mapping from parent IDs to initial child orderings.
- var initialChildren = null;
- // List of children that will be moved or removed.
- var updatedChildren = null;
-
- for (var i = 0; update = updates[i]; i++) {
- if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING ||
- update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) {
- var updatedIndex = update.fromIndex;
- var updatedChild = update.parentNode.childNodes[updatedIndex];
- var parentID = update.parentID;
-
- ("production" !== "development" ? invariant(
- updatedChild,
- 'processUpdates(): Unable to find child %s of element. This ' +
- 'probably means the DOM was unexpectedly mutated (e.g., by the ' +
- 'browser), usually due to forgetting a <tbody> when using tables, ' +
- 'nesting <p> or <a> tags, or using non-SVG elements in an <svg> '+
- 'parent. Try inspecting the child nodes of the element with React ' +
- 'ID `%s`.',
- updatedIndex,
- parentID
- ) : invariant(updatedChild));
-
- initialChildren = initialChildren || {};
- initialChildren[parentID] = initialChildren[parentID] || [];
- initialChildren[parentID][updatedIndex] = updatedChild;
-
- updatedChildren = updatedChildren || [];
- updatedChildren.push(updatedChild);
- }
- }
-
- var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList);
-
- // Remove updated children first so that `toIndex` is consistent.
- if (updatedChildren) {
- for (var j = 0; j < updatedChildren.length; j++) {
- updatedChildren[j].parentNode.removeChild(updatedChildren[j]);
- }
- }
-
- for (var k = 0; update = updates[k]; k++) {
- switch (update.type) {
- case ReactMultiChildUpdateTypes.INSERT_MARKUP:
- insertChildAt(
- update.parentNode,
- renderedMarkup[update.markupIndex],
- update.toIndex
- );
- break;
- case ReactMultiChildUpdateTypes.MOVE_EXISTING:
- insertChildAt(
- update.parentNode,
- initialChildren[update.parentID][update.fromIndex],
- update.toIndex
- );
- break;
- case ReactMultiChildUpdateTypes.TEXT_CONTENT:
- updateTextContent(
- update.parentNode,
- update.textContent
- );
- break;
- case ReactMultiChildUpdateTypes.REMOVE_NODE:
- // Already removed by the for-loop above.
- break;
- }
- }
- }
-
-};
-
-module.exports = DOMChildrenOperations;
-
-},{"./Danger":12,"./ReactMultiChildUpdateTypes":63,"./getTextContentAccessor":115,"./invariant":120}],10:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule DOMProperty
- * @typechecks static-only
- */
-
-/*jslint bitwise: true */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-
-var DOMPropertyInjection = {
- /**
- * Mapping from normalized, camelcased property names to a configuration that
- * specifies how the associated DOM property should be accessed or rendered.
- */
- MUST_USE_ATTRIBUTE: 0x1,
- MUST_USE_PROPERTY: 0x2,
- HAS_SIDE_EFFECTS: 0x4,
- HAS_BOOLEAN_VALUE: 0x8,
- HAS_NUMERIC_VALUE: 0x10,
- HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10,
- HAS_OVERLOADED_BOOLEAN_VALUE: 0x40,
-
- /**
- * Inject some specialized knowledge about the DOM. This takes a config object
- * with the following properties:
- *
- * isCustomAttribute: function that given an attribute name will return true
- * if it can be inserted into the DOM verbatim. Useful for data-* or aria-*
- * attributes where it's impossible to enumerate all of the possible
- * attribute names,
- *
- * Properties: object mapping DOM property name to one of the
- * DOMPropertyInjection constants or null. If your attribute isn't in here,
- * it won't get written to the DOM.
- *
- * DOMAttributeNames: object mapping React attribute name to the DOM
- * attribute name. Attribute names not specified use the **lowercase**
- * normalized name.
- *
- * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.
- * Property names not specified use the normalized name.
- *
- * DOMMutationMethods: Properties that require special mutation methods. If
- * `value` is undefined, the mutation method should unset the property.
- *
- * @param {object} domPropertyConfig the config as described above.
- */
- injectDOMPropertyConfig: function(domPropertyConfig) {
- var Properties = domPropertyConfig.Properties || {};
- var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};
- var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};
- var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};
-
- if (domPropertyConfig.isCustomAttribute) {
- DOMProperty._isCustomAttributeFunctions.push(
- domPropertyConfig.isCustomAttribute
- );
- }
-
- for (var propName in Properties) {
- ("production" !== "development" ? invariant(
- !DOMProperty.isStandardName.hasOwnProperty(propName),
- 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' +
- '\'%s\' which has already been injected. You may be accidentally ' +
- 'injecting the same DOM property config twice, or you may be ' +
- 'injecting two configs that have conflicting property names.',
- propName
- ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName)));
-
- DOMProperty.isStandardName[propName] = true;
-
- var lowerCased = propName.toLowerCase();
- DOMProperty.getPossibleStandardName[lowerCased] = propName;
-
- if (DOMAttributeNames.hasOwnProperty(propName)) {
- var attributeName = DOMAttributeNames[propName];
- DOMProperty.getPossibleStandardName[attributeName] = propName;
- DOMProperty.getAttributeName[propName] = attributeName;
- } else {
- DOMProperty.getAttributeName[propName] = lowerCased;
- }
-
- DOMProperty.getPropertyName[propName] =
- DOMPropertyNames.hasOwnProperty(propName) ?
- DOMPropertyNames[propName] :
- propName;
-
- if (DOMMutationMethods.hasOwnProperty(propName)) {
- DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName];
- } else {
- DOMProperty.getMutationMethod[propName] = null;
- }
-
- var propConfig = Properties[propName];
- DOMProperty.mustUseAttribute[propName] =
- propConfig & DOMPropertyInjection.MUST_USE_ATTRIBUTE;
- DOMProperty.mustUseProperty[propName] =
- propConfig & DOMPropertyInjection.MUST_USE_PROPERTY;
- DOMProperty.hasSideEffects[propName] =
- propConfig & DOMPropertyInjection.HAS_SIDE_EFFECTS;
- DOMProperty.hasBooleanValue[propName] =
- propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE;
- DOMProperty.hasNumericValue[propName] =
- propConfig & DOMPropertyInjection.HAS_NUMERIC_VALUE;
- DOMProperty.hasPositiveNumericValue[propName] =
- propConfig & DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE;
- DOMProperty.hasOverloadedBooleanValue[propName] =
- propConfig & DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE;
-
- ("production" !== "development" ? invariant(
- !DOMProperty.mustUseAttribute[propName] ||
- !DOMProperty.mustUseProperty[propName],
- 'DOMProperty: Cannot require using both attribute and property: %s',
- propName
- ) : invariant(!DOMProperty.mustUseAttribute[propName] ||
- !DOMProperty.mustUseProperty[propName]));
- ("production" !== "development" ? invariant(
- DOMProperty.mustUseProperty[propName] ||
- !DOMProperty.hasSideEffects[propName],
- 'DOMProperty: Properties that have side effects must use property: %s',
- propName
- ) : invariant(DOMProperty.mustUseProperty[propName] ||
- !DOMProperty.hasSideEffects[propName]));
- ("production" !== "development" ? invariant(
- !!DOMProperty.hasBooleanValue[propName] +
- !!DOMProperty.hasNumericValue[propName] +
- !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1,
- 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' +
- 'numeric value, but not a combination: %s',
- propName
- ) : invariant(!!DOMProperty.hasBooleanValue[propName] +
- !!DOMProperty.hasNumericValue[propName] +
- !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1));
- }
- }
-};
-var defaultValueCache = {};
-
-/**
- * DOMProperty exports lookup objects that can be used like functions:
- *
- * > DOMProperty.isValid['id']
- * true
- * > DOMProperty.isValid['foobar']
- * undefined
- *
- * Although this may be confusing, it performs better in general.
- *
- * @see http://jsperf.com/key-exists
- * @see http://jsperf.com/key-missing
- */
-var DOMProperty = {
-
- ID_ATTRIBUTE_NAME: 'data-reactid',
-
- /**
- * Checks whether a property name is a standard property.
- * @type {Object}
- */
- isStandardName: {},
-
- /**
- * Mapping from lowercase property names to the properly cased version, used
- * to warn in the case of missing properties.
- * @type {Object}
- */
- getPossibleStandardName: {},
-
- /**
- * Mapping from normalized names to attribute names that differ. Attribute
- * names are used when rendering markup or with `*Attribute()`.
- * @type {Object}
- */
- getAttributeName: {},
-
- /**
- * Mapping from normalized names to properties on DOM node instances.
- * (This includes properties that mutate due to external factors.)
- * @type {Object}
- */
- getPropertyName: {},
-
- /**
- * Mapping from normalized names to mutation methods. This will only exist if
- * mutation cannot be set simply by the property or `setAttribute()`.
- * @type {Object}
- */
- getMutationMethod: {},
-
- /**
- * Whether the property must be accessed and mutated as an object property.
- * @type {Object}
- */
- mustUseAttribute: {},
-
- /**
- * Whether the property must be accessed and mutated using `*Attribute()`.
- * (This includes anything that fails `<propName> in <element>`.)
- * @type {Object}
- */
- mustUseProperty: {},
-
- /**
- * Whether or not setting a value causes side effects such as triggering
- * resources to be loaded or text selection changes. We must ensure that
- * the value is only set if it has changed.
- * @type {Object}
- */
- hasSideEffects: {},
-
- /**
- * Whether the property should be removed when set to a falsey value.
- * @type {Object}
- */
- hasBooleanValue: {},
-
- /**
- * Whether the property must be numeric or parse as a
- * numeric and should be removed when set to a falsey value.
- * @type {Object}
- */
- hasNumericValue: {},
-
- /**
- * Whether the property must be positive numeric or parse as a positive
- * numeric and should be removed when set to a falsey value.
- * @type {Object}
- */
- hasPositiveNumericValue: {},
-
- /**
- * Whether the property can be used as a flag as well as with a value. Removed
- * when strictly equal to false; present without a value when strictly equal
- * to true; present with a value otherwise.
- * @type {Object}
- */
- hasOverloadedBooleanValue: {},
-
- /**
- * All of the isCustomAttribute() functions that have been injected.
- */
- _isCustomAttributeFunctions: [],
-
- /**
- * Checks whether a property name is a custom attribute.
- * @method
- */
- isCustomAttribute: function(attributeName) {
- for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) {
- var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i];
- if (isCustomAttributeFn(attributeName)) {
- return true;
- }
- }
- return false;
- },
-
- /**
- * Returns the default property value for a DOM property (i.e., not an
- * attribute). Most default values are '' or false, but not all. Worse yet,
- * some (in particular, `type`) vary depending on the type of element.
- *
- * TODO: Is it better to grab all the possible properties when creating an
- * element to avoid having to create the same element twice?
- */
- getDefaultValueForProperty: function(nodeName, prop) {
- var nodeDefaults = defaultValueCache[nodeName];
- var testElement;
- if (!nodeDefaults) {
- defaultValueCache[nodeName] = nodeDefaults = {};
- }
- if (!(prop in nodeDefaults)) {
- testElement = document.createElement(nodeName);
- nodeDefaults[prop] = testElement[prop];
- }
- return nodeDefaults[prop];
- },
-
- injection: DOMPropertyInjection
-};
-
-module.exports = DOMProperty;
-
-},{"./invariant":120}],11:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule DOMPropertyOperations
- * @typechecks static-only
- */
-
-"use strict";
-
-var DOMProperty = _dereq_("./DOMProperty");
-
-var escapeTextForBrowser = _dereq_("./escapeTextForBrowser");
-var memoizeStringOnly = _dereq_("./memoizeStringOnly");
-var warning = _dereq_("./warning");
-
-function shouldIgnoreValue(name, value) {
- return value == null ||
- (DOMProperty.hasBooleanValue[name] && !value) ||
- (DOMProperty.hasNumericValue[name] && isNaN(value)) ||
- (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) ||
- (DOMProperty.hasOverloadedBooleanValue[name] && value === false);
-}
-
-var processAttributeNameAndPrefix = memoizeStringOnly(function(name) {
- return escapeTextForBrowser(name) + '="';
-});
-
-if ("production" !== "development") {
- var reactProps = {
- children: true,
- dangerouslySetInnerHTML: true,
- key: true,
- ref: true
- };
- var warnedProperties = {};
-
- var warnUnknownProperty = function(name) {
- if (reactProps.hasOwnProperty(name) && reactProps[name] ||
- warnedProperties.hasOwnProperty(name) && warnedProperties[name]) {
- return;
- }
-
- warnedProperties[name] = true;
- var lowerCasedName = name.toLowerCase();
-
- // data-* attributes should be lowercase; suggest the lowercase version
- var standardName = (
- DOMProperty.isCustomAttribute(lowerCasedName) ?
- lowerCasedName :
- DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ?
- DOMProperty.getPossibleStandardName[lowerCasedName] :
- null
- );
-
- // For now, only warn when we have a suggested correction. This prevents
- // logging too much when using transferPropsTo.
- ("production" !== "development" ? warning(
- standardName == null,
- 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?'
- ) : null);
-
- };
-}
-
-/**
- * Operations for dealing with DOM properties.
- */
-var DOMPropertyOperations = {
-
- /**
- * Creates markup for the ID property.
- *
- * @param {string} id Unescaped ID.
- * @return {string} Markup string.
- */
- createMarkupForID: function(id) {
- return processAttributeNameAndPrefix(DOMProperty.ID_ATTRIBUTE_NAME) +
- escapeTextForBrowser(id) + '"';
- },
-
- /**
- * Creates markup for a property.
- *
- * @param {string} name
- * @param {*} value
- * @return {?string} Markup string, or null if the property was invalid.
- */
- createMarkupForProperty: function(name, value) {
- if (DOMProperty.isStandardName.hasOwnProperty(name) &&
- DOMProperty.isStandardName[name]) {
- if (shouldIgnoreValue(name, value)) {
- return '';
- }
- var attributeName = DOMProperty.getAttributeName[name];
- if (DOMProperty.hasBooleanValue[name] ||
- (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) {
- return escapeTextForBrowser(attributeName);
- }
- return processAttributeNameAndPrefix(attributeName) +
- escapeTextForBrowser(value) + '"';
- } else if (DOMProperty.isCustomAttribute(name)) {
- if (value == null) {
- return '';
- }
- return processAttributeNameAndPrefix(name) +
- escapeTextForBrowser(value) + '"';
- } else if ("production" !== "development") {
- warnUnknownProperty(name);
- }
- return null;
- },
-
- /**
- * Sets the value for a property on a node.
- *
- * @param {DOMElement} node
- * @param {string} name
- * @param {*} value
- */
- setValueForProperty: function(node, name, value) {
- if (DOMProperty.isStandardName.hasOwnProperty(name) &&
- DOMProperty.isStandardName[name]) {
- var mutationMethod = DOMProperty.getMutationMethod[name];
- if (mutationMethod) {
- mutationMethod(node, value);
- } else if (shouldIgnoreValue(name, value)) {
- this.deleteValueForProperty(node, name);
- } else if (DOMProperty.mustUseAttribute[name]) {
- node.setAttribute(DOMProperty.getAttributeName[name], '' + value);
- } else {
- var propName = DOMProperty.getPropertyName[name];
- if (!DOMProperty.hasSideEffects[name] || node[propName] !== value) {
- node[propName] = value;
- }
- }
- } else if (DOMProperty.isCustomAttribute(name)) {
- if (value == null) {
- node.removeAttribute(name);
- } else {
- node.setAttribute(name, '' + value);
- }
- } else if ("production" !== "development") {
- warnUnknownProperty(name);
- }
- },
-
- /**
- * Deletes the value for a property on a node.
- *
- * @param {DOMElement} node
- * @param {string} name
- */
- deleteValueForProperty: function(node, name) {
- if (DOMProperty.isStandardName.hasOwnProperty(name) &&
- DOMProperty.isStandardName[name]) {
- var mutationMethod = DOMProperty.getMutationMethod[name];
- if (mutationMethod) {
- mutationMethod(node, undefined);
- } else if (DOMProperty.mustUseAttribute[name]) {
- node.removeAttribute(DOMProperty.getAttributeName[name]);
- } else {
- var propName = DOMProperty.getPropertyName[name];
- var defaultValue = DOMProperty.getDefaultValueForProperty(
- node.nodeName,
- propName
- );
- if (!DOMProperty.hasSideEffects[name] ||
- node[propName] !== defaultValue) {
- node[propName] = defaultValue;
- }
- }
- } else if (DOMProperty.isCustomAttribute(name)) {
- node.removeAttribute(name);
- } else if ("production" !== "development") {
- warnUnknownProperty(name);
- }
- }
-
-};
-
-module.exports = DOMPropertyOperations;
-
-},{"./DOMProperty":10,"./escapeTextForBrowser":104,"./memoizeStringOnly":129,"./warning":143}],12:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule Danger
- * @typechecks static-only
- */
-
-/*jslint evil: true, sub: true */
-
-"use strict";
-
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-
-var createNodesFromMarkup = _dereq_("./createNodesFromMarkup");
-var emptyFunction = _dereq_("./emptyFunction");
-var getMarkupWrap = _dereq_("./getMarkupWrap");
-var invariant = _dereq_("./invariant");
-
-var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/;
-var RESULT_INDEX_ATTR = 'data-danger-index';
-
-/**
- * Extracts the `nodeName` from a string of markup.
- *
- * NOTE: Extracting the `nodeName` does not require a regular expression match
- * because we make assumptions about React-generated markup (i.e. there are no
- * spaces surrounding the opening tag and there is at least one attribute).
- *
- * @param {string} markup String of markup.
- * @return {string} Node name of the supplied markup.
- * @see http://jsperf.com/extract-nodename
- */
-function getNodeName(markup) {
- return markup.substring(1, markup.indexOf(' '));
-}
-
-var Danger = {
-
- /**
- * Renders markup into an array of nodes. The markup is expected to render
- * into a list of root nodes. Also, the length of `resultList` and
- * `markupList` should be the same.
- *
- * @param {array<string>} markupList List of markup strings to render.
- * @return {array<DOMElement>} List of rendered nodes.
- * @internal
- */
- dangerouslyRenderMarkup: function(markupList) {
- ("production" !== "development" ? invariant(
- ExecutionEnvironment.canUseDOM,
- 'dangerouslyRenderMarkup(...): Cannot render markup in a Worker ' +
- 'thread. This is likely a bug in the framework. Please report ' +
- 'immediately.'
- ) : invariant(ExecutionEnvironment.canUseDOM));
- var nodeName;
- var markupByNodeName = {};
- // Group markup by `nodeName` if a wrap is necessary, else by '*'.
- for (var i = 0; i < markupList.length; i++) {
- ("production" !== "development" ? invariant(
- markupList[i],
- 'dangerouslyRenderMarkup(...): Missing markup.'
- ) : invariant(markupList[i]));
- nodeName = getNodeName(markupList[i]);
- nodeName = getMarkupWrap(nodeName) ? nodeName : '*';
- markupByNodeName[nodeName] = markupByNodeName[nodeName] || [];
- markupByNodeName[nodeName][i] = markupList[i];
- }
- var resultList = [];
- var resultListAssignmentCount = 0;
- for (nodeName in markupByNodeName) {
- if (!markupByNodeName.hasOwnProperty(nodeName)) {
- continue;
- }
- var markupListByNodeName = markupByNodeName[nodeName];
-
- // This for-in loop skips the holes of the sparse array. The order of
- // iteration should follow the order of assignment, which happens to match
- // numerical index order, but we don't rely on that.
- for (var resultIndex in markupListByNodeName) {
- if (markupListByNodeName.hasOwnProperty(resultIndex)) {
- var markup = markupListByNodeName[resultIndex];
-
- // Push the requested markup with an additional RESULT_INDEX_ATTR
- // attribute. If the markup does not start with a < character, it
- // will be discarded below (with an appropriate console.error).
- markupListByNodeName[resultIndex] = markup.replace(
- OPEN_TAG_NAME_EXP,
- // This index will be parsed back out below.
- '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" '
- );
- }
- }
-
- // Render each group of markup with similar wrapping `nodeName`.
- var renderNodes = createNodesFromMarkup(
- markupListByNodeName.join(''),
- emptyFunction // Do nothing special with <script> tags.
- );
-
- for (i = 0; i < renderNodes.length; ++i) {
- var renderNode = renderNodes[i];
- if (renderNode.hasAttribute &&
- renderNode.hasAttribute(RESULT_INDEX_ATTR)) {
-
- resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR);
- renderNode.removeAttribute(RESULT_INDEX_ATTR);
-
- ("production" !== "development" ? invariant(
- !resultList.hasOwnProperty(resultIndex),
- 'Danger: Assigning to an already-occupied result index.'
- ) : invariant(!resultList.hasOwnProperty(resultIndex)));
-
- resultList[resultIndex] = renderNode;
-
- // This should match resultList.length and markupList.length when
- // we're done.
- resultListAssignmentCount += 1;
-
- } else if ("production" !== "development") {
- console.error(
- "Danger: Discarding unexpected node:",
- renderNode
- );
- }
- }
- }
-
- // Although resultList was populated out of order, it should now be a dense
- // array.
- ("production" !== "development" ? invariant(
- resultListAssignmentCount === resultList.length,
- 'Danger: Did not assign to every index of resultList.'
- ) : invariant(resultListAssignmentCount === resultList.length));
-
- ("production" !== "development" ? invariant(
- resultList.length === markupList.length,
- 'Danger: Expected markup to render %s nodes, but rendered %s.',
- markupList.length,
- resultList.length
- ) : invariant(resultList.length === markupList.length));
-
- return resultList;
- },
-
- /**
- * Replaces a node with a string of markup at its current position within its
- * parent. The markup must render into a single root node.
- *
- * @param {DOMElement} oldChild Child node to replace.
- * @param {string} markup Markup to render in place of the child node.
- * @internal
- */
- dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) {
- ("production" !== "development" ? invariant(
- ExecutionEnvironment.canUseDOM,
- 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' +
- 'worker thread. This is likely a bug in the framework. Please report ' +
- 'immediately.'
- ) : invariant(ExecutionEnvironment.canUseDOM));
- ("production" !== "development" ? invariant(markup, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(markup));
- ("production" !== "development" ? invariant(
- oldChild.tagName.toLowerCase() !== 'html',
- 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' +
- '<html> node. This is because browser quirks make this unreliable ' +
- 'and/or slow. If you want to render to the root you must use ' +
- 'server rendering. See renderComponentToString().'
- ) : invariant(oldChild.tagName.toLowerCase() !== 'html'));
-
- var newChild = createNodesFromMarkup(markup, emptyFunction)[0];
- oldChild.parentNode.replaceChild(newChild, oldChild);
- }
-
-};
-
-module.exports = Danger;
-
-},{"./ExecutionEnvironment":21,"./createNodesFromMarkup":100,"./emptyFunction":102,"./getMarkupWrap":112,"./invariant":120}],13:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule DefaultEventPluginOrder
- */
-
-"use strict";
-
- var keyOf = _dereq_("./keyOf");
-
-/**
- * Module that is injectable into `EventPluginHub`, that specifies a
- * deterministic ordering of `EventPlugin`s. A convenient way to reason about
- * plugins, without having to package every one of them. This is better than
- * having plugins be ordered in the same order that they are injected because
- * that ordering would be influenced by the packaging order.
- * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
- * preventing default on events is convenient in `SimpleEventPlugin` handlers.
- */
-var DefaultEventPluginOrder = [
- keyOf({ResponderEventPlugin: null}),
- keyOf({SimpleEventPlugin: null}),
- keyOf({TapEventPlugin: null}),
- keyOf({EnterLeaveEventPlugin: null}),
- keyOf({ChangeEventPlugin: null}),
- keyOf({SelectEventPlugin: null}),
- keyOf({CompositionEventPlugin: null}),
- keyOf({BeforeInputEventPlugin: null}),
- keyOf({AnalyticsEventPlugin: null}),
- keyOf({MobileSafariClickEventPlugin: null})
-];
-
-module.exports = DefaultEventPluginOrder;
-
-},{"./keyOf":127}],14:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule EnterLeaveEventPlugin
- * @typechecks static-only
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-var EventPropagators = _dereq_("./EventPropagators");
-var SyntheticMouseEvent = _dereq_("./SyntheticMouseEvent");
-
-var ReactMount = _dereq_("./ReactMount");
-var keyOf = _dereq_("./keyOf");
-
-var topLevelTypes = EventConstants.topLevelTypes;
-var getFirstReactDOM = ReactMount.getFirstReactDOM;
-
-var eventTypes = {
- mouseEnter: {
- registrationName: keyOf({onMouseEnter: null}),
- dependencies: [
- topLevelTypes.topMouseOut,
- topLevelTypes.topMouseOver
- ]
- },
- mouseLeave: {
- registrationName: keyOf({onMouseLeave: null}),
- dependencies: [
- topLevelTypes.topMouseOut,
- topLevelTypes.topMouseOver
- ]
- }
-};
-
-var extractedEvents = [null, null];
-
-var EnterLeaveEventPlugin = {
-
- eventTypes: eventTypes,
-
- /**
- * For almost every interaction we care about, there will be both a top-level
- * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
- * we do not extract duplicate events. However, moving the mouse into the
- * browser from outside will not fire a `mouseout` event. In this case, we use
- * the `mouseover` top-level event.
- *
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {DOMEventTarget} topLevelTarget The listening component root node.
- * @param {string} topLevelTargetID ID of `topLevelTarget`.
- * @param {object} nativeEvent Native browser event.
- * @return {*} An accumulation of synthetic events.
- * @see {EventPluginHub.extractEvents}
- */
- extractEvents: function(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent) {
- if (topLevelType === topLevelTypes.topMouseOver &&
- (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
- return null;
- }
- if (topLevelType !== topLevelTypes.topMouseOut &&
- topLevelType !== topLevelTypes.topMouseOver) {
- // Must not be a mouse in or mouse out - ignoring.
- return null;
- }
-
- var win;
- if (topLevelTarget.window === topLevelTarget) {
- // `topLevelTarget` is probably a window object.
- win = topLevelTarget;
- } else {
- // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
- var doc = topLevelTarget.ownerDocument;
- if (doc) {
- win = doc.defaultView || doc.parentWindow;
- } else {
- win = window;
- }
- }
-
- var from, to;
- if (topLevelType === topLevelTypes.topMouseOut) {
- from = topLevelTarget;
- to =
- getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) ||
- win;
- } else {
- from = win;
- to = topLevelTarget;
- }
-
- if (from === to) {
- // Nothing pertains to our managed components.
- return null;
- }
-
- var fromID = from ? ReactMount.getID(from) : '';
- var toID = to ? ReactMount.getID(to) : '';
-
- var leave = SyntheticMouseEvent.getPooled(
- eventTypes.mouseLeave,
- fromID,
- nativeEvent
- );
- leave.type = 'mouseleave';
- leave.target = from;
- leave.relatedTarget = to;
-
- var enter = SyntheticMouseEvent.getPooled(
- eventTypes.mouseEnter,
- toID,
- nativeEvent
- );
- enter.type = 'mouseenter';
- enter.target = to;
- enter.relatedTarget = from;
-
- EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID);
-
- extractedEvents[0] = leave;
- extractedEvents[1] = enter;
-
- return extractedEvents;
- }
-
-};
-
-module.exports = EnterLeaveEventPlugin;
-
-},{"./EventConstants":15,"./EventPropagators":20,"./ReactMount":61,"./SyntheticMouseEvent":88,"./keyOf":127}],15:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule EventConstants
- */
-
-"use strict";
-
-var keyMirror = _dereq_("./keyMirror");
-
-var PropagationPhases = keyMirror({bubbled: null, captured: null});
-
-/**
- * Types of raw signals from the browser caught at the top level.
- */
-var topLevelTypes = keyMirror({
- topBlur: null,
- topChange: null,
- topClick: null,
- topCompositionEnd: null,
- topCompositionStart: null,
- topCompositionUpdate: null,
- topContextMenu: null,
- topCopy: null,
- topCut: null,
- topDoubleClick: null,
- topDrag: null,
- topDragEnd: null,
- topDragEnter: null,
- topDragExit: null,
- topDragLeave: null,
- topDragOver: null,
- topDragStart: null,
- topDrop: null,
- topError: null,
- topFocus: null,
- topInput: null,
- topKeyDown: null,
- topKeyPress: null,
- topKeyUp: null,
- topLoad: null,
- topMouseDown: null,
- topMouseMove: null,
- topMouseOut: null,
- topMouseOver: null,
- topMouseUp: null,
- topPaste: null,
- topReset: null,
- topScroll: null,
- topSelectionChange: null,
- topSubmit: null,
- topTextInput: null,
- topTouchCancel: null,
- topTouchEnd: null,
- topTouchMove: null,
- topTouchStart: null,
- topWheel: null
-});
-
-var EventConstants = {
- topLevelTypes: topLevelTypes,
- PropagationPhases: PropagationPhases
-};
-
-module.exports = EventConstants;
-
-},{"./keyMirror":126}],16:[function(_dereq_,module,exports){
-/**
- * @providesModule EventListener
- * @typechecks
- */
-
-var emptyFunction = _dereq_("./emptyFunction");
-
-/**
- * Upstream version of event listener. Does not take into account specific
- * nature of platform.
- */
-var EventListener = {
- /**
- * Listen to DOM events during the bubble phase.
- *
- * @param {DOMEventTarget} target DOM element to register listener on.
- * @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
- * @param {function} callback Callback function.
- * @return {object} Object with a `remove` method.
- */
- listen: function(target, eventType, callback) {
- if (target.addEventListener) {
- target.addEventListener(eventType, callback, false);
- return {
- remove: function() {
- target.removeEventListener(eventType, callback, false);
- }
- };
- } else if (target.attachEvent) {
- target.attachEvent('on' + eventType, callback);
- return {
- remove: function() {
- target.detachEvent('on' + eventType, callback);
- }
- };
- }
- },
-
- /**
- * Listen to DOM events during the capture phase.
- *
- * @param {DOMEventTarget} target DOM element to register listener on.
- * @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
- * @param {function} callback Callback function.
- * @return {object} Object with a `remove` method.
- */
- capture: function(target, eventType, callback) {
- if (!target.addEventListener) {
- if ("production" !== "development") {
- console.error(
- 'Attempted to listen to events during the capture phase on a ' +
- 'browser that does not support the capture phase. Your application ' +
- 'will not receive some events.'
- );
- }
- return {
- remove: emptyFunction
- };
- } else {
- target.addEventListener(eventType, callback, true);
- return {
- remove: function() {
- target.removeEventListener(eventType, callback, true);
- }
- };
- }
- },
-
- registerDefault: function() {}
-};
-
-module.exports = EventListener;
-
-},{"./emptyFunction":102}],17:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule EventPluginHub
- */
-
-"use strict";
-
-var EventPluginRegistry = _dereq_("./EventPluginRegistry");
-var EventPluginUtils = _dereq_("./EventPluginUtils");
-
-var accumulate = _dereq_("./accumulate");
-var forEachAccumulated = _dereq_("./forEachAccumulated");
-var invariant = _dereq_("./invariant");
-var isEventSupported = _dereq_("./isEventSupported");
-var monitorCodeUse = _dereq_("./monitorCodeUse");
-
-/**
- * Internal store for event listeners
- */
-var listenerBank = {};
-
-/**
- * Internal queue of events that have accumulated their dispatches and are
- * waiting to have their dispatches executed.
- */
-var eventQueue = null;
-
-/**
- * Dispatches an event and releases it back into the pool, unless persistent.
- *
- * @param {?object} event Synthetic event to be dispatched.
- * @private
- */
-var executeDispatchesAndRelease = function(event) {
- if (event) {
- var executeDispatch = EventPluginUtils.executeDispatch;
- // Plugins can provide custom behavior when dispatching events.
- var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event);
- if (PluginModule && PluginModule.executeDispatch) {
- executeDispatch = PluginModule.executeDispatch;
- }
- EventPluginUtils.executeDispatchesInOrder(event, executeDispatch);
-
- if (!event.isPersistent()) {
- event.constructor.release(event);
- }
- }
-};
-
-/**
- * - `InstanceHandle`: [required] Module that performs logical traversals of DOM
- * hierarchy given ids of the logical DOM elements involved.
- */
-var InstanceHandle = null;
-
-function validateInstanceHandle() {
- var invalid = !InstanceHandle||
- !InstanceHandle.traverseTwoPhase ||
- !InstanceHandle.traverseEnterLeave;
- if (invalid) {
- throw new Error('InstanceHandle not injected before use!');
- }
-}
-
-/**
- * This is a unified interface for event plugins to be installed and configured.
- *
- * Event plugins can implement the following properties:
- *
- * `extractEvents` {function(string, DOMEventTarget, string, object): *}
- * Required. When a top-level event is fired, this method is expected to
- * extract synthetic events that will in turn be queued and dispatched.
- *
- * `eventTypes` {object}
- * Optional, plugins that fire events must publish a mapping of registration
- * names that are used to register listeners. Values of this mapping must
- * be objects that contain `registrationName` or `phasedRegistrationNames`.
- *
- * `executeDispatch` {function(object, function, string)}
- * Optional, allows plugins to override how an event gets dispatched. By
- * default, the listener is simply invoked.
- *
- * Each plugin that is injected into `EventsPluginHub` is immediately operable.
- *
- * @public
- */
-var EventPluginHub = {
-
- /**
- * Methods for injecting dependencies.
- */
- injection: {
-
- /**
- * @param {object} InjectedMount
- * @public
- */
- injectMount: EventPluginUtils.injection.injectMount,
-
- /**
- * @param {object} InjectedInstanceHandle
- * @public
- */
- injectInstanceHandle: function(InjectedInstanceHandle) {
- InstanceHandle = InjectedInstanceHandle;
- if ("production" !== "development") {
- validateInstanceHandle();
- }
- },
-
- getInstanceHandle: function() {
- if ("production" !== "development") {
- validateInstanceHandle();
- }
- return InstanceHandle;
- },
-
- /**
- * @param {array} InjectedEventPluginOrder
- * @public
- */
- injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,
-
- /**
- * @param {object} injectedNamesToPlugins Map from names to plugin modules.
- */
- injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName
-
- },
-
- eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs,
-
- registrationNameModules: EventPluginRegistry.registrationNameModules,
-
- /**
- * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent.
- *
- * @param {string} id ID of the DOM element.
- * @param {string} registrationName Name of listener (e.g. `onClick`).
- * @param {?function} listener The callback to store.
- */
- putListener: function(id, registrationName, listener) {
- ("production" !== "development" ? invariant(
- !listener || typeof listener === 'function',
- 'Expected %s listener to be a function, instead got type %s',
- registrationName, typeof listener
- ) : invariant(!listener || typeof listener === 'function'));
-
- if ("production" !== "development") {
- // IE8 has no API for event capturing and the `onScroll` event doesn't
- // bubble.
- if (registrationName === 'onScroll' &&
- !isEventSupported('scroll', true)) {
- monitorCodeUse('react_no_scroll_event');
- console.warn('This browser doesn\'t support the `onScroll` event');
- }
- }
- var bankForRegistrationName =
- listenerBank[registrationName] || (listenerBank[registrationName] = {});
- bankForRegistrationName[id] = listener;
- },
-
- /**
- * @param {string} id ID of the DOM element.
- * @param {string} registrationName Name of listener (e.g. `onClick`).
- * @return {?function} The stored callback.
- */
- getListener: function(id, registrationName) {
- var bankForRegistrationName = listenerBank[registrationName];
- return bankForRegistrationName && bankForRegistrationName[id];
- },
-
- /**
- * Deletes a listener from the registration bank.
- *
- * @param {string} id ID of the DOM element.
- * @param {string} registrationName Name of listener (e.g. `onClick`).
- */
- deleteListener: function(id, registrationName) {
- var bankForRegistrationName = listenerBank[registrationName];
- if (bankForRegistrationName) {
- delete bankForRegistrationName[id];
- }
- },
-
- /**
- * Deletes all listeners for the DOM element with the supplied ID.
- *
- * @param {string} id ID of the DOM element.
- */
- deleteAllListeners: function(id) {
- for (var registrationName in listenerBank) {
- delete listenerBank[registrationName][id];
- }
- },
-
- /**
- * Allows registered plugins an opportunity to extract events from top-level
- * native browser events.
- *
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {DOMEventTarget} topLevelTarget The listening component root node.
- * @param {string} topLevelTargetID ID of `topLevelTarget`.
- * @param {object} nativeEvent Native browser event.
- * @return {*} An accumulation of synthetic events.
- * @internal
- */
- extractEvents: function(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent) {
- var events;
- var plugins = EventPluginRegistry.plugins;
- for (var i = 0, l = plugins.length; i < l; i++) {
- // Not every plugin in the ordering may be loaded at runtime.
- var possiblePlugin = plugins[i];
- if (possiblePlugin) {
- var extractedEvents = possiblePlugin.extractEvents(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent
- );
- if (extractedEvents) {
- events = accumulate(events, extractedEvents);
- }
- }
- }
- return events;
- },
-
- /**
- * Enqueues a synthetic event that should be dispatched when
- * `processEventQueue` is invoked.
- *
- * @param {*} events An accumulation of synthetic events.
- * @internal
- */
- enqueueEvents: function(events) {
- if (events) {
- eventQueue = accumulate(eventQueue, events);
- }
- },
-
- /**
- * Dispatches all synthetic events on the event queue.
- *
- * @internal
- */
- processEventQueue: function() {
- // Set `eventQueue` to null before processing it so that we can tell if more
- // events get enqueued while processing.
- var processingEventQueue = eventQueue;
- eventQueue = null;
- forEachAccumulated(processingEventQueue, executeDispatchesAndRelease);
- ("production" !== "development" ? invariant(
- !eventQueue,
- 'processEventQueue(): Additional events were enqueued while processing ' +
- 'an event queue. Support for this has not yet been implemented.'
- ) : invariant(!eventQueue));
- },
-
- /**
- * These are needed for tests only. Do not use!
- */
- __purge: function() {
- listenerBank = {};
- },
-
- __getListenerBank: function() {
- return listenerBank;
- }
-
-};
-
-module.exports = EventPluginHub;
-
-},{"./EventPluginRegistry":18,"./EventPluginUtils":19,"./accumulate":94,"./forEachAccumulated":107,"./invariant":120,"./isEventSupported":121,"./monitorCodeUse":134}],18:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule EventPluginRegistry
- * @typechecks static-only
- */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Injectable ordering of event plugins.
- */
-var EventPluginOrder = null;
-
-/**
- * Injectable mapping from names to event plugin modules.
- */
-var namesToPlugins = {};
-
-/**
- * Recomputes the plugin list using the injected plugins and plugin ordering.
- *
- * @private
- */
-function recomputePluginOrdering() {
- if (!EventPluginOrder) {
- // Wait until an `EventPluginOrder` is injected.
- return;
- }
- for (var pluginName in namesToPlugins) {
- var PluginModule = namesToPlugins[pluginName];
- var pluginIndex = EventPluginOrder.indexOf(pluginName);
- ("production" !== "development" ? invariant(
- pluginIndex > -1,
- 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' +
- 'the plugin ordering, `%s`.',
- pluginName
- ) : invariant(pluginIndex > -1));
- if (EventPluginRegistry.plugins[pluginIndex]) {
- continue;
- }
- ("production" !== "development" ? invariant(
- PluginModule.extractEvents,
- 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' +
- 'method, but `%s` does not.',
- pluginName
- ) : invariant(PluginModule.extractEvents));
- EventPluginRegistry.plugins[pluginIndex] = PluginModule;
- var publishedEvents = PluginModule.eventTypes;
- for (var eventName in publishedEvents) {
- ("production" !== "development" ? invariant(
- publishEventForPlugin(
- publishedEvents[eventName],
- PluginModule,
- eventName
- ),
- 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.',
- eventName,
- pluginName
- ) : invariant(publishEventForPlugin(
- publishedEvents[eventName],
- PluginModule,
- eventName
- )));
- }
- }
-}
-
-/**
- * Publishes an event so that it can be dispatched by the supplied plugin.
- *
- * @param {object} dispatchConfig Dispatch configuration for the event.
- * @param {object} PluginModule Plugin publishing the event.
- * @return {boolean} True if the event was successfully published.
- * @private
- */
-function publishEventForPlugin(dispatchConfig, PluginModule, eventName) {
- ("production" !== "development" ? invariant(
- !EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName),
- 'EventPluginHub: More than one plugin attempted to publish the same ' +
- 'event name, `%s`.',
- eventName
- ) : invariant(!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName)));
- EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig;
-
- var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
- if (phasedRegistrationNames) {
- for (var phaseName in phasedRegistrationNames) {
- if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
- var phasedRegistrationName = phasedRegistrationNames[phaseName];
- publishRegistrationName(
- phasedRegistrationName,
- PluginModule,
- eventName
- );
- }
- }
- return true;
- } else if (dispatchConfig.registrationName) {
- publishRegistrationName(
- dispatchConfig.registrationName,
- PluginModule,
- eventName
- );
- return true;
- }
- return false;
-}
-
-/**
- * Publishes a registration name that is used to identify dispatched events and
- * can be used with `EventPluginHub.putListener` to register listeners.
- *
- * @param {string} registrationName Registration name to add.
- * @param {object} PluginModule Plugin publishing the event.
- * @private
- */
-function publishRegistrationName(registrationName, PluginModule, eventName) {
- ("production" !== "development" ? invariant(
- !EventPluginRegistry.registrationNameModules[registrationName],
- 'EventPluginHub: More than one plugin attempted to publish the same ' +
- 'registration name, `%s`.',
- registrationName
- ) : invariant(!EventPluginRegistry.registrationNameModules[registrationName]));
- EventPluginRegistry.registrationNameModules[registrationName] = PluginModule;
- EventPluginRegistry.registrationNameDependencies[registrationName] =
- PluginModule.eventTypes[eventName].dependencies;
-}
-
-/**
- * Registers plugins so that they can extract and dispatch events.
- *
- * @see {EventPluginHub}
- */
-var EventPluginRegistry = {
-
- /**
- * Ordered list of injected plugins.
- */
- plugins: [],
-
- /**
- * Mapping from event name to dispatch config
- */
- eventNameDispatchConfigs: {},
-
- /**
- * Mapping from registration name to plugin module
- */
- registrationNameModules: {},
-
- /**
- * Mapping from registration name to event name
- */
- registrationNameDependencies: {},
-
- /**
- * Injects an ordering of plugins (by plugin name). This allows the ordering
- * to be decoupled from injection of the actual plugins so that ordering is
- * always deterministic regardless of packaging, on-the-fly injection, etc.
- *
- * @param {array} InjectedEventPluginOrder
- * @internal
- * @see {EventPluginHub.injection.injectEventPluginOrder}
- */
- injectEventPluginOrder: function(InjectedEventPluginOrder) {
- ("production" !== "development" ? invariant(
- !EventPluginOrder,
- 'EventPluginRegistry: Cannot inject event plugin ordering more than ' +
- 'once. You are likely trying to load more than one copy of React.'
- ) : invariant(!EventPluginOrder));
- // Clone the ordering so it cannot be dynamically mutated.
- EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder);
- recomputePluginOrdering();
- },
-
- /**
- * Injects plugins to be used by `EventPluginHub`. The plugin names must be
- * in the ordering injected by `injectEventPluginOrder`.
- *
- * Plugins can be injected as part of page initialization or on-the-fly.
- *
- * @param {object} injectedNamesToPlugins Map from names to plugin modules.
- * @internal
- * @see {EventPluginHub.injection.injectEventPluginsByName}
- */
- injectEventPluginsByName: function(injectedNamesToPlugins) {
- var isOrderingDirty = false;
- for (var pluginName in injectedNamesToPlugins) {
- if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
- continue;
- }
- var PluginModule = injectedNamesToPlugins[pluginName];
- if (!namesToPlugins.hasOwnProperty(pluginName) ||
- namesToPlugins[pluginName] !== PluginModule) {
- ("production" !== "development" ? invariant(
- !namesToPlugins[pluginName],
- 'EventPluginRegistry: Cannot inject two different event plugins ' +
- 'using the same name, `%s`.',
- pluginName
- ) : invariant(!namesToPlugins[pluginName]));
- namesToPlugins[pluginName] = PluginModule;
- isOrderingDirty = true;
- }
- }
- if (isOrderingDirty) {
- recomputePluginOrdering();
- }
- },
-
- /**
- * Looks up the plugin for the supplied event.
- *
- * @param {object} event A synthetic event.
- * @return {?object} The plugin that created the supplied event.
- * @internal
- */
- getPluginModuleForEvent: function(event) {
- var dispatchConfig = event.dispatchConfig;
- if (dispatchConfig.registrationName) {
- return EventPluginRegistry.registrationNameModules[
- dispatchConfig.registrationName
- ] || null;
- }
- for (var phase in dispatchConfig.phasedRegistrationNames) {
- if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) {
- continue;
- }
- var PluginModule = EventPluginRegistry.registrationNameModules[
- dispatchConfig.phasedRegistrationNames[phase]
- ];
- if (PluginModule) {
- return PluginModule;
- }
- }
- return null;
- },
-
- /**
- * Exposed for unit testing.
- * @private
- */
- _resetEventPlugins: function() {
- EventPluginOrder = null;
- for (var pluginName in namesToPlugins) {
- if (namesToPlugins.hasOwnProperty(pluginName)) {
- delete namesToPlugins[pluginName];
- }
- }
- EventPluginRegistry.plugins.length = 0;
-
- var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs;
- for (var eventName in eventNameDispatchConfigs) {
- if (eventNameDispatchConfigs.hasOwnProperty(eventName)) {
- delete eventNameDispatchConfigs[eventName];
- }
- }
-
- var registrationNameModules = EventPluginRegistry.registrationNameModules;
- for (var registrationName in registrationNameModules) {
- if (registrationNameModules.hasOwnProperty(registrationName)) {
- delete registrationNameModules[registrationName];
- }
- }
- }
-
-};
-
-module.exports = EventPluginRegistry;
-
-},{"./invariant":120}],19:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule EventPluginUtils
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Injected dependencies:
- */
-
-/**
- * - `Mount`: [required] Module that can convert between React dom IDs and
- * actual node references.
- */
-var injection = {
- Mount: null,
- injectMount: function(InjectedMount) {
- injection.Mount = InjectedMount;
- if ("production" !== "development") {
- ("production" !== "development" ? invariant(
- InjectedMount && InjectedMount.getNode,
- 'EventPluginUtils.injection.injectMount(...): Injected Mount module ' +
- 'is missing getNode.'
- ) : invariant(InjectedMount && InjectedMount.getNode));
- }
- }
-};
-
-var topLevelTypes = EventConstants.topLevelTypes;
-
-function isEndish(topLevelType) {
- return topLevelType === topLevelTypes.topMouseUp ||
- topLevelType === topLevelTypes.topTouchEnd ||
- topLevelType === topLevelTypes.topTouchCancel;
-}
-
-function isMoveish(topLevelType) {
- return topLevelType === topLevelTypes.topMouseMove ||
- topLevelType === topLevelTypes.topTouchMove;
-}
-function isStartish(topLevelType) {
- return topLevelType === topLevelTypes.topMouseDown ||
- topLevelType === topLevelTypes.topTouchStart;
-}
-
-
-var validateEventDispatches;
-if ("production" !== "development") {
- validateEventDispatches = function(event) {
- var dispatchListeners = event._dispatchListeners;
- var dispatchIDs = event._dispatchIDs;
-
- var listenersIsArr = Array.isArray(dispatchListeners);
- var idsIsArr = Array.isArray(dispatchIDs);
- var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0;
- var listenersLen = listenersIsArr ?
- dispatchListeners.length :
- dispatchListeners ? 1 : 0;
-
- ("production" !== "development" ? invariant(
- idsIsArr === listenersIsArr && IDsLen === listenersLen,
- 'EventPluginUtils: Invalid `event`.'
- ) : invariant(idsIsArr === listenersIsArr && IDsLen === listenersLen));
- };
-}
-
-/**
- * Invokes `cb(event, listener, id)`. Avoids using call if no scope is
- * provided. The `(listener,id)` pair effectively forms the "dispatch" but are
- * kept separate to conserve memory.
- */
-function forEachEventDispatch(event, cb) {
- var dispatchListeners = event._dispatchListeners;
- var dispatchIDs = event._dispatchIDs;
- if ("production" !== "development") {
- validateEventDispatches(event);
- }
- if (Array.isArray(dispatchListeners)) {
- for (var i = 0; i < dispatchListeners.length; i++) {
- if (event.isPropagationStopped()) {
- break;
- }
- // Listeners and IDs are two parallel arrays that are always in sync.
- cb(event, dispatchListeners[i], dispatchIDs[i]);
- }
- } else if (dispatchListeners) {
- cb(event, dispatchListeners, dispatchIDs);
- }
-}
-
-/**
- * Default implementation of PluginModule.executeDispatch().
- * @param {SyntheticEvent} SyntheticEvent to handle
- * @param {function} Application-level callback
- * @param {string} domID DOM id to pass to the callback.
- */
-function executeDispatch(event, listener, domID) {
- event.currentTarget = injection.Mount.getNode(domID);
- var returnValue = listener(event, domID);
- event.currentTarget = null;
- return returnValue;
-}
-
-/**
- * Standard/simple iteration through an event's collected dispatches.
- */
-function executeDispatchesInOrder(event, executeDispatch) {
- forEachEventDispatch(event, executeDispatch);
- event._dispatchListeners = null;
- event._dispatchIDs = null;
-}
-
-/**
- * Standard/simple iteration through an event's collected dispatches, but stops
- * at the first dispatch execution returning true, and returns that id.
- *
- * @return id of the first dispatch execution who's listener returns true, or
- * null if no listener returned true.
- */
-function executeDispatchesInOrderStopAtTrueImpl(event) {
- var dispatchListeners = event._dispatchListeners;
- var dispatchIDs = event._dispatchIDs;
- if ("production" !== "development") {
- validateEventDispatches(event);
- }
- if (Array.isArray(dispatchListeners)) {
- for (var i = 0; i < dispatchListeners.length; i++) {
- if (event.isPropagationStopped()) {
- break;
- }
- // Listeners and IDs are two parallel arrays that are always in sync.
- if (dispatchListeners[i](event, dispatchIDs[i])) {
- return dispatchIDs[i];
- }
- }
- } else if (dispatchListeners) {
- if (dispatchListeners(event, dispatchIDs)) {
- return dispatchIDs;
- }
- }
- return null;
-}
-
-/**
- * @see executeDispatchesInOrderStopAtTrueImpl
- */
-function executeDispatchesInOrderStopAtTrue(event) {
- var ret = executeDispatchesInOrderStopAtTrueImpl(event);
- event._dispatchIDs = null;
- event._dispatchListeners = null;
- return ret;
-}
-
-/**
- * Execution of a "direct" dispatch - there must be at most one dispatch
- * accumulated on the event or it is considered an error. It doesn't really make
- * sense for an event with multiple dispatches (bubbled) to keep track of the
- * return values at each dispatch execution, but it does tend to make sense when
- * dealing with "direct" dispatches.
- *
- * @return The return value of executing the single dispatch.
- */
-function executeDirectDispatch(event) {
- if ("production" !== "development") {
- validateEventDispatches(event);
- }
- var dispatchListener = event._dispatchListeners;
- var dispatchID = event._dispatchIDs;
- ("production" !== "development" ? invariant(
- !Array.isArray(dispatchListener),
- 'executeDirectDispatch(...): Invalid `event`.'
- ) : invariant(!Array.isArray(dispatchListener)));
- var res = dispatchListener ?
- dispatchListener(event, dispatchID) :
- null;
- event._dispatchListeners = null;
- event._dispatchIDs = null;
- return res;
-}
-
-/**
- * @param {SyntheticEvent} event
- * @return {bool} True iff number of dispatches accumulated is greater than 0.
- */
-function hasDispatches(event) {
- return !!event._dispatchListeners;
-}
-
-/**
- * General utilities that are useful in creating custom Event Plugins.
- */
-var EventPluginUtils = {
- isEndish: isEndish,
- isMoveish: isMoveish,
- isStartish: isStartish,
-
- executeDirectDispatch: executeDirectDispatch,
- executeDispatch: executeDispatch,
- executeDispatchesInOrder: executeDispatchesInOrder,
- executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue,
- hasDispatches: hasDispatches,
- injection: injection,
- useTouchEvents: false
-};
-
-module.exports = EventPluginUtils;
-
-},{"./EventConstants":15,"./invariant":120}],20:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule EventPropagators
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-var EventPluginHub = _dereq_("./EventPluginHub");
-
-var accumulate = _dereq_("./accumulate");
-var forEachAccumulated = _dereq_("./forEachAccumulated");
-
-var PropagationPhases = EventConstants.PropagationPhases;
-var getListener = EventPluginHub.getListener;
-
-/**
- * Some event types have a notion of different registration names for different
- * "phases" of propagation. This finds listeners by a given phase.
- */
-function listenerAtPhase(id, event, propagationPhase) {
- var registrationName =
- event.dispatchConfig.phasedRegistrationNames[propagationPhase];
- return getListener(id, registrationName);
-}
-
-/**
- * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
- * here, allows us to not have to bind or create functions for each event.
- * Mutating the event's members allows us to not have to create a wrapping
- * "dispatch" object that pairs the event with the listener.
- */
-function accumulateDirectionalDispatches(domID, upwards, event) {
- if ("production" !== "development") {
- if (!domID) {
- throw new Error('Dispatching id must not be null');
- }
- }
- var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured;
- var listener = listenerAtPhase(domID, event, phase);
- if (listener) {
- event._dispatchListeners = accumulate(event._dispatchListeners, listener);
- event._dispatchIDs = accumulate(event._dispatchIDs, domID);
- }
-}
-
-/**
- * Collect dispatches (must be entirely collected before dispatching - see unit
- * tests). Lazily allocate the array to conserve memory. We must loop through
- * each event and perform the traversal for each one. We can not perform a
- * single traversal for the entire collection of events because each event may
- * have a different target.
- */
-function accumulateTwoPhaseDispatchesSingle(event) {
- if (event && event.dispatchConfig.phasedRegistrationNames) {
- EventPluginHub.injection.getInstanceHandle().traverseTwoPhase(
- event.dispatchMarker,
- accumulateDirectionalDispatches,
- event
- );
- }
-}
-
-
-/**
- * Accumulates without regard to direction, does not look for phased
- * registration names. Same as `accumulateDirectDispatchesSingle` but without
- * requiring that the `dispatchMarker` be the same as the dispatched ID.
- */
-function accumulateDispatches(id, ignoredDirection, event) {
- if (event && event.dispatchConfig.registrationName) {
- var registrationName = event.dispatchConfig.registrationName;
- var listener = getListener(id, registrationName);
- if (listener) {
- event._dispatchListeners = accumulate(event._dispatchListeners, listener);
- event._dispatchIDs = accumulate(event._dispatchIDs, id);
- }
- }
-}
-
-/**
- * Accumulates dispatches on an `SyntheticEvent`, but only for the
- * `dispatchMarker`.
- * @param {SyntheticEvent} event
- */
-function accumulateDirectDispatchesSingle(event) {
- if (event && event.dispatchConfig.registrationName) {
- accumulateDispatches(event.dispatchMarker, null, event);
- }
-}
-
-function accumulateTwoPhaseDispatches(events) {
- forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
-}
-
-function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) {
- EventPluginHub.injection.getInstanceHandle().traverseEnterLeave(
- fromID,
- toID,
- accumulateDispatches,
- leave,
- enter
- );
-}
-
-
-function accumulateDirectDispatches(events) {
- forEachAccumulated(events, accumulateDirectDispatchesSingle);
-}
-
-
-
-/**
- * A small set of propagation patterns, each of which will accept a small amount
- * of information, and generate a set of "dispatch ready event objects" - which
- * are sets of events that have already been annotated with a set of dispatched
- * listener functions/ids. The API is designed this way to discourage these
- * propagation strategies from actually executing the dispatches, since we
- * always want to collect the entire set of dispatches before executing event a
- * single one.
- *
- * @constructor EventPropagators
- */
-var EventPropagators = {
- accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,
- accumulateDirectDispatches: accumulateDirectDispatches,
- accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches
-};
-
-module.exports = EventPropagators;
-
-},{"./EventConstants":15,"./EventPluginHub":17,"./accumulate":94,"./forEachAccumulated":107}],21:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ExecutionEnvironment
- */
-
-/*jslint evil: true */
-
-"use strict";
-
-var canUseDOM = !!(
- typeof window !== 'undefined' &&
- window.document &&
- window.document.createElement
-);
-
-/**
- * Simple, lightweight module assisting with the detection and context of
- * Worker. Helps avoid circular dependencies and allows code to reason about
- * whether or not they are in a Worker, even if they never include the main
- * `ReactWorker` dependency.
- */
-var ExecutionEnvironment = {
-
- canUseDOM: canUseDOM,
-
- canUseWorkers: typeof Worker !== 'undefined',
-
- canUseEventListeners:
- canUseDOM && !!(window.addEventListener || window.attachEvent),
-
- canUseViewport: canUseDOM && !!window.screen,
-
- isInWorker: !canUseDOM // For now, this is true - might change in the future.
-
-};
-
-module.exports = ExecutionEnvironment;
-
-},{}],22:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule HTMLDOMPropertyConfig
- */
-
-/*jslint bitwise: true*/
-
-"use strict";
-
-var DOMProperty = _dereq_("./DOMProperty");
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-
-var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;
-var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY;
-var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE;
-var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS;
-var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE;
-var HAS_POSITIVE_NUMERIC_VALUE =
- DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE;
-var HAS_OVERLOADED_BOOLEAN_VALUE =
- DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE;
-
-var hasSVG;
-if (ExecutionEnvironment.canUseDOM) {
- var implementation = document.implementation;
- hasSVG = (
- implementation &&
- implementation.hasFeature &&
- implementation.hasFeature(
- 'http://www.w3.org/TR/SVG11/feature#BasicStructure',
- '1.1'
- )
- );
-}
-
-
-var HTMLDOMPropertyConfig = {
- isCustomAttribute: RegExp.prototype.test.bind(
- /^(data|aria)-[a-z_][a-z\d_.\-]*$/
- ),
- Properties: {
- /**
- * Standard Properties
- */
- accept: null,
- accessKey: null,
- action: null,
- allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
- allowTransparency: MUST_USE_ATTRIBUTE,
- alt: null,
- async: HAS_BOOLEAN_VALUE,
- autoComplete: null,
- // autoFocus is polyfilled/normalized by AutoFocusMixin
- // autoFocus: HAS_BOOLEAN_VALUE,
- autoPlay: HAS_BOOLEAN_VALUE,
- cellPadding: null,
- cellSpacing: null,
- charSet: MUST_USE_ATTRIBUTE,
- checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
- // To set className on SVG elements, it's necessary to use .setAttribute;
- // this works on HTML elements too in all browsers except IE8. Conveniently,
- // IE8 doesn't support SVG and so we can simply use the attribute in
- // browsers that support SVG and the property in browsers that don't,
- // regardless of whether the element is HTML or SVG.
- className: hasSVG ? MUST_USE_ATTRIBUTE : MUST_USE_PROPERTY,
- cols: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
- colSpan: null,
- content: null,
- contentEditable: null,
- contextMenu: MUST_USE_ATTRIBUTE,
- controls: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
- coords: null,
- crossOrigin: null,
- data: null, // For `<object />` acts as `src`.
- dateTime: MUST_USE_ATTRIBUTE,
- defer: HAS_BOOLEAN_VALUE,
- dir: null,
- disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
- download: HAS_OVERLOADED_BOOLEAN_VALUE,
- draggable: null,
- encType: null,
- form: MUST_USE_ATTRIBUTE,
- formNoValidate: HAS_BOOLEAN_VALUE,
- frameBorder: MUST_USE_ATTRIBUTE,
- height: MUST_USE_ATTRIBUTE,
- hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
- href: null,
- hrefLang: null,
- htmlFor: null,
- httpEquiv: null,
- icon: null,
- id: MUST_USE_PROPERTY,
- label: null,
- lang: null,
- list: null,
- loop: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
- max: null,
- maxLength: MUST_USE_ATTRIBUTE,
- mediaGroup: null,
- method: null,
- min: null,
- multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
- muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
- name: null,
- noValidate: HAS_BOOLEAN_VALUE,
- pattern: null,
- placeholder: null,
- poster: null,
- preload: null,
- radioGroup: null,
- readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
- rel: null,
- required: HAS_BOOLEAN_VALUE,
- role: MUST_USE_ATTRIBUTE,
- rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
- rowSpan: null,
- sandbox: null,
- scope: null,
- scrollLeft: MUST_USE_PROPERTY,
- scrolling: null,
- scrollTop: MUST_USE_PROPERTY,
- seamless: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE,
- selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
- shape: null,
- size: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE,
- span: HAS_POSITIVE_NUMERIC_VALUE,
- spellCheck: null,
- src: null,
- srcDoc: MUST_USE_PROPERTY,
- srcSet: null,
- start: HAS_NUMERIC_VALUE,
- step: null,
- style: null,
- tabIndex: null,
- target: null,
- title: null,
- type: null,
- useMap: null,
- value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS,
- width: MUST_USE_ATTRIBUTE,
- wmode: MUST_USE_ATTRIBUTE,
-
- /**
- * Non-standard Properties
- */
- autoCapitalize: null, // Supported in Mobile Safari for keyboard hints
- autoCorrect: null, // Supported in Mobile Safari for keyboard hints
- itemProp: MUST_USE_ATTRIBUTE, // Microdata: http://schema.org/docs/gs.html
- itemScope: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, // Microdata: http://schema.org/docs/gs.html
- itemType: MUST_USE_ATTRIBUTE, // Microdata: http://schema.org/docs/gs.html
- property: null // Supports OG in meta tags
- },
- DOMAttributeNames: {
- className: 'class',
- htmlFor: 'for',
- httpEquiv: 'http-equiv'
- },
- DOMPropertyNames: {
- autoCapitalize: 'autocapitalize',
- autoComplete: 'autocomplete',
- autoCorrect: 'autocorrect',
- autoFocus: 'autofocus',
- autoPlay: 'autoplay',
- encType: 'enctype',
- hrefLang: 'hreflang',
- radioGroup: 'radiogroup',
- spellCheck: 'spellcheck',
- srcDoc: 'srcdoc',
- srcSet: 'srcset'
- }
-};
-
-module.exports = HTMLDOMPropertyConfig;
-
-},{"./DOMProperty":10,"./ExecutionEnvironment":21}],23:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule LinkedValueUtils
- * @typechecks static-only
- */
-
-"use strict";
-
-var ReactPropTypes = _dereq_("./ReactPropTypes");
-
-var invariant = _dereq_("./invariant");
-
-var hasReadOnlyValue = {
- 'button': true,
- 'checkbox': true,
- 'image': true,
- 'hidden': true,
- 'radio': true,
- 'reset': true,
- 'submit': true
-};
-
-function _assertSingleLink(input) {
- ("production" !== "development" ? invariant(
- input.props.checkedLink == null || input.props.valueLink == null,
- 'Cannot provide a checkedLink and a valueLink. If you want to use ' +
- 'checkedLink, you probably don\'t want to use valueLink and vice versa.'
- ) : invariant(input.props.checkedLink == null || input.props.valueLink == null));
-}
-function _assertValueLink(input) {
- _assertSingleLink(input);
- ("production" !== "development" ? invariant(
- input.props.value == null && input.props.onChange == null,
- 'Cannot provide a valueLink and a value or onChange event. If you want ' +
- 'to use value or onChange, you probably don\'t want to use valueLink.'
- ) : invariant(input.props.value == null && input.props.onChange == null));
-}
-
-function _assertCheckedLink(input) {
- _assertSingleLink(input);
- ("production" !== "development" ? invariant(
- input.props.checked == null && input.props.onChange == null,
- 'Cannot provide a checkedLink and a checked property or onChange event. ' +
- 'If you want to use checked or onChange, you probably don\'t want to ' +
- 'use checkedLink'
- ) : invariant(input.props.checked == null && input.props.onChange == null));
-}
-
-/**
- * @param {SyntheticEvent} e change event to handle
- */
-function _handleLinkedValueChange(e) {
- /*jshint validthis:true */
- this.props.valueLink.requestChange(e.target.value);
-}
-
-/**
- * @param {SyntheticEvent} e change event to handle
- */
-function _handleLinkedCheckChange(e) {
- /*jshint validthis:true */
- this.props.checkedLink.requestChange(e.target.checked);
-}
-
-/**
- * Provide a linked `value` attribute for controlled forms. You should not use
- * this outside of the ReactDOM controlled form components.
- */
-var LinkedValueUtils = {
- Mixin: {
- propTypes: {
- value: function(props, propName, componentName) {
- if (!props[propName] ||
- hasReadOnlyValue[props.type] ||
- props.onChange ||
- props.readOnly ||
- props.disabled) {
- return;
- }
- return new Error(
- 'You provided a `value` prop to a form field without an ' +
- '`onChange` handler. This will render a read-only field. If ' +
- 'the field should be mutable use `defaultValue`. Otherwise, ' +
- 'set either `onChange` or `readOnly`.'
- );
- },
- checked: function(props, propName, componentName) {
- if (!props[propName] ||
- props.onChange ||
- props.readOnly ||
- props.disabled) {
- return;
- }
- return new Error(
- 'You provided a `checked` prop to a form field without an ' +
- '`onChange` handler. This will render a read-only field. If ' +
- 'the field should be mutable use `defaultChecked`. Otherwise, ' +
- 'set either `onChange` or `readOnly`.'
- );
- },
- onChange: ReactPropTypes.func
- }
- },
-
- /**
- * @param {ReactComponent} input Form component
- * @return {*} current value of the input either from value prop or link.
- */
- getValue: function(input) {
- if (input.props.valueLink) {
- _assertValueLink(input);
- return input.props.valueLink.value;
- }
- return input.props.value;
- },
-
- /**
- * @param {ReactComponent} input Form component
- * @return {*} current checked status of the input either from checked prop
- * or link.
- */
- getChecked: function(input) {
- if (input.props.checkedLink) {
- _assertCheckedLink(input);
- return input.props.checkedLink.value;
- }
- return input.props.checked;
- },
-
- /**
- * @param {ReactComponent} input Form component
- * @return {function} change callback either from onChange prop or link.
- */
- getOnChange: function(input) {
- if (input.props.valueLink) {
- _assertValueLink(input);
- return _handleLinkedValueChange;
- } else if (input.props.checkedLink) {
- _assertCheckedLink(input);
- return _handleLinkedCheckChange;
- }
- return input.props.onChange;
- }
-};
-
-module.exports = LinkedValueUtils;
-
-},{"./ReactPropTypes":69,"./invariant":120}],24:[function(_dereq_,module,exports){
-/**
- * Copyright 2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule LocalEventTrapMixin
- */
-
-"use strict";
-
-var ReactBrowserEventEmitter = _dereq_("./ReactBrowserEventEmitter");
-
-var accumulate = _dereq_("./accumulate");
-var forEachAccumulated = _dereq_("./forEachAccumulated");
-var invariant = _dereq_("./invariant");
-
-function remove(event) {
- event.remove();
-}
-
-var LocalEventTrapMixin = {
- trapBubbledEvent:function(topLevelType, handlerBaseName) {
- ("production" !== "development" ? invariant(this.isMounted(), 'Must be mounted to trap events') : invariant(this.isMounted()));
- var listener = ReactBrowserEventEmitter.trapBubbledEvent(
- topLevelType,
- handlerBaseName,
- this.getDOMNode()
- );
- this._localEventListeners = accumulate(this._localEventListeners, listener);
- },
-
- // trapCapturedEvent would look nearly identical. We don't implement that
- // method because it isn't currently needed.
-
- componentWillUnmount:function() {
- if (this._localEventListeners) {
- forEachAccumulated(this._localEventListeners, remove);
- }
- }
-};
-
-module.exports = LocalEventTrapMixin;
-
-},{"./ReactBrowserEventEmitter":29,"./accumulate":94,"./forEachAccumulated":107,"./invariant":120}],25:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule MobileSafariClickEventPlugin
- * @typechecks static-only
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-
-var emptyFunction = _dereq_("./emptyFunction");
-
-var topLevelTypes = EventConstants.topLevelTypes;
-
-/**
- * Mobile Safari does not fire properly bubble click events on non-interactive
- * elements, which means delegated click listeners do not fire. The workaround
- * for this bug involves attaching an empty click listener on the target node.
- *
- * This particular plugin works around the bug by attaching an empty click
- * listener on `touchstart` (which does fire on every element).
- */
-var MobileSafariClickEventPlugin = {
-
- eventTypes: null,
-
- /**
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {DOMEventTarget} topLevelTarget The listening component root node.
- * @param {string} topLevelTargetID ID of `topLevelTarget`.
- * @param {object} nativeEvent Native browser event.
- * @return {*} An accumulation of synthetic events.
- * @see {EventPluginHub.extractEvents}
- */
- extractEvents: function(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent) {
- if (topLevelType === topLevelTypes.topTouchStart) {
- var target = nativeEvent.target;
- if (target && !target.onclick) {
- target.onclick = emptyFunction;
- }
- }
- }
-
-};
-
-module.exports = MobileSafariClickEventPlugin;
-
-},{"./EventConstants":15,"./emptyFunction":102}],26:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule PooledClass
- */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Static poolers. Several custom versions for each potential number of
- * arguments. A completely generic pooler is easy to implement, but would
- * require accessing the `arguments` object. In each of these, `this` refers to
- * the Class itself, not an instance. If any others are needed, simply add them
- * here, or in their own files.
- */
-var oneArgumentPooler = function(copyFieldsFrom) {
- var Klass = this;
- if (Klass.instancePool.length) {
- var instance = Klass.instancePool.pop();
- Klass.call(instance, copyFieldsFrom);
- return instance;
- } else {
- return new Klass(copyFieldsFrom);
- }
-};
-
-var twoArgumentPooler = function(a1, a2) {
- var Klass = this;
- if (Klass.instancePool.length) {
- var instance = Klass.instancePool.pop();
- Klass.call(instance, a1, a2);
- return instance;
- } else {
- return new Klass(a1, a2);
- }
-};
-
-var threeArgumentPooler = function(a1, a2, a3) {
- var Klass = this;
- if (Klass.instancePool.length) {
- var instance = Klass.instancePool.pop();
- Klass.call(instance, a1, a2, a3);
- return instance;
- } else {
- return new Klass(a1, a2, a3);
- }
-};
-
-var fiveArgumentPooler = function(a1, a2, a3, a4, a5) {
- var Klass = this;
- if (Klass.instancePool.length) {
- var instance = Klass.instancePool.pop();
- Klass.call(instance, a1, a2, a3, a4, a5);
- return instance;
- } else {
- return new Klass(a1, a2, a3, a4, a5);
- }
-};
-
-var standardReleaser = function(instance) {
- var Klass = this;
- ("production" !== "development" ? invariant(
- instance instanceof Klass,
- 'Trying to release an instance into a pool of a different type.'
- ) : invariant(instance instanceof Klass));
- if (instance.destructor) {
- instance.destructor();
- }
- if (Klass.instancePool.length < Klass.poolSize) {
- Klass.instancePool.push(instance);
- }
-};
-
-var DEFAULT_POOL_SIZE = 10;
-var DEFAULT_POOLER = oneArgumentPooler;
-
-/**
- * Augments `CopyConstructor` to be a poolable class, augmenting only the class
- * itself (statically) not adding any prototypical fields. Any CopyConstructor
- * you give this may have a `poolSize` property, and will look for a
- * prototypical `destructor` on instances (optional).
- *
- * @param {Function} CopyConstructor Constructor that can be used to reset.
- * @param {Function} pooler Customizable pooler.
- */
-var addPoolingTo = function(CopyConstructor, pooler) {
- var NewKlass = CopyConstructor;
- NewKlass.instancePool = [];
- NewKlass.getPooled = pooler || DEFAULT_POOLER;
- if (!NewKlass.poolSize) {
- NewKlass.poolSize = DEFAULT_POOL_SIZE;
- }
- NewKlass.release = standardReleaser;
- return NewKlass;
-};
-
-var PooledClass = {
- addPoolingTo: addPoolingTo,
- oneArgumentPooler: oneArgumentPooler,
- twoArgumentPooler: twoArgumentPooler,
- threeArgumentPooler: threeArgumentPooler,
- fiveArgumentPooler: fiveArgumentPooler
-};
-
-module.exports = PooledClass;
-
-},{"./invariant":120}],27:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule React
- */
-
-"use strict";
-
-var DOMPropertyOperations = _dereq_("./DOMPropertyOperations");
-var EventPluginUtils = _dereq_("./EventPluginUtils");
-var ReactChildren = _dereq_("./ReactChildren");
-var ReactComponent = _dereq_("./ReactComponent");
-var ReactCompositeComponent = _dereq_("./ReactCompositeComponent");
-var ReactContext = _dereq_("./ReactContext");
-var ReactCurrentOwner = _dereq_("./ReactCurrentOwner");
-var ReactDescriptor = _dereq_("./ReactDescriptor");
-var ReactDOM = _dereq_("./ReactDOM");
-var ReactDOMComponent = _dereq_("./ReactDOMComponent");
-var ReactDefaultInjection = _dereq_("./ReactDefaultInjection");
-var ReactInstanceHandles = _dereq_("./ReactInstanceHandles");
-var ReactMount = _dereq_("./ReactMount");
-var ReactMultiChild = _dereq_("./ReactMultiChild");
-var ReactPerf = _dereq_("./ReactPerf");
-var ReactPropTypes = _dereq_("./ReactPropTypes");
-var ReactServerRendering = _dereq_("./ReactServerRendering");
-var ReactTextComponent = _dereq_("./ReactTextComponent");
-
-var onlyChild = _dereq_("./onlyChild");
-
-ReactDefaultInjection.inject();
-
-var React = {
- Children: {
- map: ReactChildren.map,
- forEach: ReactChildren.forEach,
- count: ReactChildren.count,
- only: onlyChild
- },
- DOM: ReactDOM,
- PropTypes: ReactPropTypes,
- initializeTouchEvents: function(shouldUseTouch) {
- EventPluginUtils.useTouchEvents = shouldUseTouch;
- },
- createClass: ReactCompositeComponent.createClass,
- createDescriptor: function(type, props, children) {
- var args = Array.prototype.slice.call(arguments, 1);
- return type.apply(null, args);
- },
- constructAndRenderComponent: ReactMount.constructAndRenderComponent,
- constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID,
- renderComponent: ReactPerf.measure(
- 'React',
- 'renderComponent',
- ReactMount.renderComponent
- ),
- renderComponentToString: ReactServerRendering.renderComponentToString,
- renderComponentToStaticMarkup:
- ReactServerRendering.renderComponentToStaticMarkup,
- unmountComponentAtNode: ReactMount.unmountComponentAtNode,
- isValidClass: ReactDescriptor.isValidFactory,
- isValidComponent: ReactDescriptor.isValidDescriptor,
- withContext: ReactContext.withContext,
- __internals: {
- Component: ReactComponent,
- CurrentOwner: ReactCurrentOwner,
- DOMComponent: ReactDOMComponent,
- DOMPropertyOperations: DOMPropertyOperations,
- InstanceHandles: ReactInstanceHandles,
- Mount: ReactMount,
- MultiChild: ReactMultiChild,
- TextComponent: ReactTextComponent
- }
-};
-
-if ("production" !== "development") {
- var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
- if (ExecutionEnvironment.canUseDOM &&
- window.top === window.self &&
- navigator.userAgent.indexOf('Chrome') > -1) {
- console.debug(
- 'Download the React DevTools for a better development experience: ' +
- 'http://fb.me/react-devtools'
- );
-
- var expectedFeatures = [
- // shims
- Array.isArray,
- Array.prototype.every,
- Array.prototype.forEach,
- Array.prototype.indexOf,
- Array.prototype.map,
- Date.now,
- Function.prototype.bind,
- Object.keys,
- String.prototype.split,
- String.prototype.trim,
-
- // shams
- Object.create,
- Object.freeze
- ];
-
- for (var i in expectedFeatures) {
- if (!expectedFeatures[i]) {
- console.error(
- 'One or more ES5 shim/shams expected by React are not available: ' +
- 'http://fb.me/react-warning-polyfills'
- );
- break;
- }
- }
- }
-}
-
-// Version exists only in the open-source version of React, not in Facebook's
-// internal version.
-React.version = '0.11.1';
-
-module.exports = React;
-
-},{"./DOMPropertyOperations":11,"./EventPluginUtils":19,"./ExecutionEnvironment":21,"./ReactChildren":30,"./ReactComponent":31,"./ReactCompositeComponent":33,"./ReactContext":34,"./ReactCurrentOwner":35,"./ReactDOM":36,"./ReactDOMComponent":38,"./ReactDefaultInjection":48,"./ReactDescriptor":51,"./ReactInstanceHandles":59,"./ReactMount":61,"./ReactMultiChild":62,"./ReactPerf":65,"./ReactPropTypes":69,"./ReactServerRendering":73,"./ReactTextComponent":75,"./onlyChild":135}],28:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactBrowserComponentMixin
- */
-
-"use strict";
-
-var ReactEmptyComponent = _dereq_("./ReactEmptyComponent");
-var ReactMount = _dereq_("./ReactMount");
-
-var invariant = _dereq_("./invariant");
-
-var ReactBrowserComponentMixin = {
- /**
- * Returns the DOM node rendered by this component.
- *
- * @return {DOMElement} The root node of this component.
- * @final
- * @protected
- */
- getDOMNode: function() {
- ("production" !== "development" ? invariant(
- this.isMounted(),
- 'getDOMNode(): A component must be mounted to have a DOM node.'
- ) : invariant(this.isMounted()));
- if (ReactEmptyComponent.isNullComponentID(this._rootNodeID)) {
- return null;
- }
- return ReactMount.getNode(this._rootNodeID);
- }
-};
-
-module.exports = ReactBrowserComponentMixin;
-
-},{"./ReactEmptyComponent":53,"./ReactMount":61,"./invariant":120}],29:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactBrowserEventEmitter
- * @typechecks static-only
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-var EventPluginHub = _dereq_("./EventPluginHub");
-var EventPluginRegistry = _dereq_("./EventPluginRegistry");
-var ReactEventEmitterMixin = _dereq_("./ReactEventEmitterMixin");
-var ViewportMetrics = _dereq_("./ViewportMetrics");
-
-var isEventSupported = _dereq_("./isEventSupported");
-var merge = _dereq_("./merge");
-
-/**
- * Summary of `ReactBrowserEventEmitter` event handling:
- *
- * - Top-level delegation is used to trap most native browser events. This
- * may only occur in the main thread and is the responsibility of
- * ReactEventListener, which is injected and can therefore support pluggable
- * event sources. This is the only work that occurs in the main thread.
- *
- * - We normalize and de-duplicate events to account for browser quirks. This
- * may be done in the worker thread.
- *
- * - Forward these native events (with the associated top-level type used to
- * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
- * to extract any synthetic events.
- *
- * - The `EventPluginHub` will then process each event by annotating them with
- * "dispatches", a sequence of listeners and IDs that care about that event.
- *
- * - The `EventPluginHub` then dispatches the events.
- *
- * Overview of React and the event system:
- *
- * +------------+ .
- * | DOM | .
- * +------------+ .
- * | .
- * v .
- * +------------+ .
- * | ReactEvent | .
- * | Listener | .
- * +------------+ . +-----------+
- * | . +--------+|SimpleEvent|
- * | . | |Plugin |
- * +-----|------+ . v +-----------+
- * | | | . +--------------+ +------------+
- * | +-----------.--->|EventPluginHub| | Event |
- * | | . | | +-----------+ | Propagators|
- * | ReactEvent | . | | |TapEvent | |------------|
- * | Emitter | . | |<---+|Plugin | |other plugin|
- * | | . | | +-----------+ | utilities |
- * | +-----------.--->| | +------------+
- * | | | . +--------------+
- * +-----|------+ . ^ +-----------+
- * | . | |Enter/Leave|
- * + . +-------+|Plugin |
- * +-------------+ . +-----------+
- * | application | .
- * |-------------| .
- * | | .
- * | | .
- * +-------------+ .
- * .
- * React Core . General Purpose Event Plugin System
- */
-
-var alreadyListeningTo = {};
-var isMonitoringScrollValue = false;
-var reactTopListenersCounter = 0;
-
-// For events like 'submit' which don't consistently bubble (which we trap at a
-// lower node than `document`), binding at `document` would cause duplicate
-// events so we don't include them here
-var topEventMapping = {
- topBlur: 'blur',
- topChange: 'change',
- topClick: 'click',
- topCompositionEnd: 'compositionend',
- topCompositionStart: 'compositionstart',
- topCompositionUpdate: 'compositionupdate',
- topContextMenu: 'contextmenu',
- topCopy: 'copy',
- topCut: 'cut',
- topDoubleClick: 'dblclick',
- topDrag: 'drag',
- topDragEnd: 'dragend',
- topDragEnter: 'dragenter',
- topDragExit: 'dragexit',
- topDragLeave: 'dragleave',
- topDragOver: 'dragover',
- topDragStart: 'dragstart',
- topDrop: 'drop',
- topFocus: 'focus',
- topInput: 'input',
- topKeyDown: 'keydown',
- topKeyPress: 'keypress',
- topKeyUp: 'keyup',
- topMouseDown: 'mousedown',
- topMouseMove: 'mousemove',
- topMouseOut: 'mouseout',
- topMouseOver: 'mouseover',
- topMouseUp: 'mouseup',
- topPaste: 'paste',
- topScroll: 'scroll',
- topSelectionChange: 'selectionchange',
- topTextInput: 'textInput',
- topTouchCancel: 'touchcancel',
- topTouchEnd: 'touchend',
- topTouchMove: 'touchmove',
- topTouchStart: 'touchstart',
- topWheel: 'wheel'
-};
-
-/**
- * To ensure no conflicts with other potential React instances on the page
- */
-var topListenersIDKey = "_reactListenersID" + String(Math.random()).slice(2);
-
-function getListeningForDocument(mountAt) {
- // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
- // directly.
- if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
- mountAt[topListenersIDKey] = reactTopListenersCounter++;
- alreadyListeningTo[mountAt[topListenersIDKey]] = {};
- }
- return alreadyListeningTo[mountAt[topListenersIDKey]];
-}
-
-/**
- * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For
- * example:
- *
- * ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction);
- *
- * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'.
- *
- * @internal
- */
-var ReactBrowserEventEmitter = merge(ReactEventEmitterMixin, {
-
- /**
- * Injectable event backend
- */
- ReactEventListener: null,
-
- injection: {
- /**
- * @param {object} ReactEventListener
- */
- injectReactEventListener: function(ReactEventListener) {
- ReactEventListener.setHandleTopLevel(
- ReactBrowserEventEmitter.handleTopLevel
- );
- ReactBrowserEventEmitter.ReactEventListener = ReactEventListener;
- }
- },
-
- /**
- * Sets whether or not any created callbacks should be enabled.
- *
- * @param {boolean} enabled True if callbacks should be enabled.
- */
- setEnabled: function(enabled) {
- if (ReactBrowserEventEmitter.ReactEventListener) {
- ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled);
- }
- },
-
- /**
- * @return {boolean} True if callbacks are enabled.
- */
- isEnabled: function() {
- return !!(
- ReactBrowserEventEmitter.ReactEventListener &&
- ReactBrowserEventEmitter.ReactEventListener.isEnabled()
- );
- },
-
- /**
- * We listen for bubbled touch events on the document object.
- *
- * Firefox v8.01 (and possibly others) exhibited strange behavior when
- * mounting `onmousemove` events at some node that was not the document
- * element. The symptoms were that if your mouse is not moving over something
- * contained within that mount point (for example on the background) the
- * top-level listeners for `onmousemove` won't be called. However, if you
- * register the `mousemove` on the document object, then it will of course
- * catch all `mousemove`s. This along with iOS quirks, justifies restricting
- * top-level listeners to the document object only, at least for these
- * movement types of events and possibly all events.
- *
- * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
- *
- * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
- * they bubble to document.
- *
- * @param {string} registrationName Name of listener (e.g. `onClick`).
- * @param {object} contentDocumentHandle Document which owns the container
- */
- listenTo: function(registrationName, contentDocumentHandle) {
- var mountAt = contentDocumentHandle;
- var isListening = getListeningForDocument(mountAt);
- var dependencies = EventPluginRegistry.
- registrationNameDependencies[registrationName];
-
- var topLevelTypes = EventConstants.topLevelTypes;
- for (var i = 0, l = dependencies.length; i < l; i++) {
- var dependency = dependencies[i];
- if (!(
- isListening.hasOwnProperty(dependency) &&
- isListening[dependency]
- )) {
- if (dependency === topLevelTypes.topWheel) {
- if (isEventSupported('wheel')) {
- ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
- topLevelTypes.topWheel,
- 'wheel',
- mountAt
- );
- } else if (isEventSupported('mousewheel')) {
- ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
- topLevelTypes.topWheel,
- 'mousewheel',
- mountAt
- );
- } else {
- // Firefox needs to capture a different mouse scroll event.
- // @see http://www.quirksmode.org/dom/events/tests/scroll.html
- ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
- topLevelTypes.topWheel,
- 'DOMMouseScroll',
- mountAt
- );
- }
- } else if (dependency === topLevelTypes.topScroll) {
-
- if (isEventSupported('scroll', true)) {
- ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
- topLevelTypes.topScroll,
- 'scroll',
- mountAt
- );
- } else {
- ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
- topLevelTypes.topScroll,
- 'scroll',
- ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE
- );
- }
- } else if (dependency === topLevelTypes.topFocus ||
- dependency === topLevelTypes.topBlur) {
-
- if (isEventSupported('focus', true)) {
- ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
- topLevelTypes.topFocus,
- 'focus',
- mountAt
- );
- ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
- topLevelTypes.topBlur,
- 'blur',
- mountAt
- );
- } else if (isEventSupported('focusin')) {
- // IE has `focusin` and `focusout` events which bubble.
- // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
- ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
- topLevelTypes.topFocus,
- 'focusin',
- mountAt
- );
- ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
- topLevelTypes.topBlur,
- 'focusout',
- mountAt
- );
- }
-
- // to make sure blur and focus event listeners are only attached once
- isListening[topLevelTypes.topBlur] = true;
- isListening[topLevelTypes.topFocus] = true;
- } else if (topEventMapping.hasOwnProperty(dependency)) {
- ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
- dependency,
- topEventMapping[dependency],
- mountAt
- );
- }
-
- isListening[dependency] = true;
- }
- }
- },
-
- trapBubbledEvent: function(topLevelType, handlerBaseName, handle) {
- return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(
- topLevelType,
- handlerBaseName,
- handle
- );
- },
-
- trapCapturedEvent: function(topLevelType, handlerBaseName, handle) {
- return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(
- topLevelType,
- handlerBaseName,
- handle
- );
- },
-
- /**
- * Listens to window scroll and resize events. We cache scroll values so that
- * application code can access them without triggering reflows.
- *
- * NOTE: Scroll events do not bubble.
- *
- * @see http://www.quirksmode.org/dom/events/scroll.html
- */
- ensureScrollValueMonitoring: function(){
- if (!isMonitoringScrollValue) {
- var refresh = ViewportMetrics.refreshScrollValues;
- ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh);
- isMonitoringScrollValue = true;
- }
- },
-
- eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs,
-
- registrationNameModules: EventPluginHub.registrationNameModules,
-
- putListener: EventPluginHub.putListener,
-
- getListener: EventPluginHub.getListener,
-
- deleteListener: EventPluginHub.deleteListener,
-
- deleteAllListeners: EventPluginHub.deleteAllListeners
-
-});
-
-module.exports = ReactBrowserEventEmitter;
-
-},{"./EventConstants":15,"./EventPluginHub":17,"./EventPluginRegistry":18,"./ReactEventEmitterMixin":55,"./ViewportMetrics":93,"./isEventSupported":121,"./merge":130}],30:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactChildren
- */
-
-"use strict";
-
-var PooledClass = _dereq_("./PooledClass");
-
-var traverseAllChildren = _dereq_("./traverseAllChildren");
-var warning = _dereq_("./warning");
-
-var twoArgumentPooler = PooledClass.twoArgumentPooler;
-var threeArgumentPooler = PooledClass.threeArgumentPooler;
-
-/**
- * PooledClass representing the bookkeeping associated with performing a child
- * traversal. Allows avoiding binding callbacks.
- *
- * @constructor ForEachBookKeeping
- * @param {!function} forEachFunction Function to perform traversal with.
- * @param {?*} forEachContext Context to perform context with.
- */
-function ForEachBookKeeping(forEachFunction, forEachContext) {
- this.forEachFunction = forEachFunction;
- this.forEachContext = forEachContext;
-}
-PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler);
-
-function forEachSingleChild(traverseContext, child, name, i) {
- var forEachBookKeeping = traverseContext;
- forEachBookKeeping.forEachFunction.call(
- forEachBookKeeping.forEachContext, child, i);
-}
-
-/**
- * Iterates through children that are typically specified as `props.children`.
- *
- * The provided forEachFunc(child, index) will be called for each
- * leaf child.
- *
- * @param {?*} children Children tree container.
- * @param {function(*, int)} forEachFunc.
- * @param {*} forEachContext Context for forEachContext.
- */
-function forEachChildren(children, forEachFunc, forEachContext) {
- if (children == null) {
- return children;
- }
-
- var traverseContext =
- ForEachBookKeeping.getPooled(forEachFunc, forEachContext);
- traverseAllChildren(children, forEachSingleChild, traverseContext);
- ForEachBookKeeping.release(traverseContext);
-}
-
-/**
- * PooledClass representing the bookkeeping associated with performing a child
- * mapping. Allows avoiding binding callbacks.
- *
- * @constructor MapBookKeeping
- * @param {!*} mapResult Object containing the ordered map of results.
- * @param {!function} mapFunction Function to perform mapping with.
- * @param {?*} mapContext Context to perform mapping with.
- */
-function MapBookKeeping(mapResult, mapFunction, mapContext) {
- this.mapResult = mapResult;
- this.mapFunction = mapFunction;
- this.mapContext = mapContext;
-}
-PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler);
-
-function mapSingleChildIntoContext(traverseContext, child, name, i) {
- var mapBookKeeping = traverseContext;
- var mapResult = mapBookKeeping.mapResult;
-
- var keyUnique = !mapResult.hasOwnProperty(name);
- ("production" !== "development" ? warning(
- keyUnique,
- 'ReactChildren.map(...): Encountered two children with the same key, ' +
- '`%s`. Child keys must be unique; when two children share a key, only ' +
- 'the first child will be used.',
- name
- ) : null);
-
- if (keyUnique) {
- var mappedChild =
- mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);
- mapResult[name] = mappedChild;
- }
-}
-
-/**
- * Maps children that are typically specified as `props.children`.
- *
- * The provided mapFunction(child, key, index) will be called for each
- * leaf child.
- *
- * TODO: This may likely break any calls to `ReactChildren.map` that were
- * previously relying on the fact that we guarded against null children.
- *
- * @param {?*} children Children tree container.
- * @param {function(*, int)} mapFunction.
- * @param {*} mapContext Context for mapFunction.
- * @return {object} Object containing the ordered map of results.
- */
-function mapChildren(children, func, context) {
- if (children == null) {
- return children;
- }
-
- var mapResult = {};
- var traverseContext = MapBookKeeping.getPooled(mapResult, func, context);
- traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);
- MapBookKeeping.release(traverseContext);
- return mapResult;
-}
-
-function forEachSingleChildDummy(traverseContext, child, name, i) {
- return null;
-}
-
-/**
- * Count the number of children that are typically specified as
- * `props.children`.
- *
- * @param {?*} children Children tree container.
- * @return {number} The number of children.
- */
-function countChildren(children, context) {
- return traverseAllChildren(children, forEachSingleChildDummy, null);
-}
-
-var ReactChildren = {
- forEach: forEachChildren,
- map: mapChildren,
- count: countChildren
-};
-
-module.exports = ReactChildren;
-
-},{"./PooledClass":26,"./traverseAllChildren":142,"./warning":143}],31:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactComponent
- */
-
-"use strict";
-
-var ReactDescriptor = _dereq_("./ReactDescriptor");
-var ReactOwner = _dereq_("./ReactOwner");
-var ReactUpdates = _dereq_("./ReactUpdates");
-
-var invariant = _dereq_("./invariant");
-var keyMirror = _dereq_("./keyMirror");
-var merge = _dereq_("./merge");
-
-/**
- * Every React component is in one of these life cycles.
- */
-var ComponentLifeCycle = keyMirror({
- /**
- * Mounted components have a DOM node representation and are capable of
- * receiving new props.
- */
- MOUNTED: null,
- /**
- * Unmounted components are inactive and cannot receive new props.
- */
- UNMOUNTED: null
-});
-
-var injected = false;
-
-/**
- * Optionally injectable environment dependent cleanup hook. (server vs.
- * browser etc). Example: A browser system caches DOM nodes based on component
- * ID and must remove that cache entry when this instance is unmounted.
- *
- * @private
- */
-var unmountIDFromEnvironment = null;
-
-/**
- * The "image" of a component tree, is the platform specific (typically
- * serialized) data that represents a tree of lower level UI building blocks.
- * On the web, this "image" is HTML markup which describes a construction of
- * low level `div` and `span` nodes. Other platforms may have different
- * encoding of this "image". This must be injected.
- *
- * @private
- */
-var mountImageIntoNode = null;
-
-/**
- * Components are the basic units of composition in React.
- *
- * Every component accepts a set of keyed input parameters known as "props" that
- * are initialized by the constructor. Once a component is mounted, the props
- * can be mutated using `setProps` or `replaceProps`.
- *
- * Every component is capable of the following operations:
- *
- * `mountComponent`
- * Initializes the component, renders markup, and registers event listeners.
- *
- * `receiveComponent`
- * Updates the rendered DOM nodes to match the given component.
- *
- * `unmountComponent`
- * Releases any resources allocated by this component.
- *
- * Components can also be "owned" by other components. Being owned by another
- * component means being constructed by that component. This is different from
- * being the child of a component, which means having a DOM representation that
- * is a child of the DOM representation of that component.
- *
- * @class ReactComponent
- */
-var ReactComponent = {
-
- injection: {
- injectEnvironment: function(ReactComponentEnvironment) {
- ("production" !== "development" ? invariant(
- !injected,
- 'ReactComponent: injectEnvironment() can only be called once.'
- ) : invariant(!injected));
- mountImageIntoNode = ReactComponentEnvironment.mountImageIntoNode;
- unmountIDFromEnvironment =
- ReactComponentEnvironment.unmountIDFromEnvironment;
- ReactComponent.BackendIDOperations =
- ReactComponentEnvironment.BackendIDOperations;
- injected = true;
- }
- },
-
- /**
- * @internal
- */
- LifeCycle: ComponentLifeCycle,
-
- /**
- * Injected module that provides ability to mutate individual properties.
- * Injected into the base class because many different subclasses need access
- * to this.
- *
- * @internal
- */
- BackendIDOperations: null,
-
- /**
- * Base functionality for every ReactComponent constructor. Mixed into the
- * `ReactComponent` prototype, but exposed statically for easy access.
- *
- * @lends {ReactComponent.prototype}
- */
- Mixin: {
-
- /**
- * Checks whether or not this component is mounted.
- *
- * @return {boolean} True if mounted, false otherwise.
- * @final
- * @protected
- */
- isMounted: function() {
- return this._lifeCycleState === ComponentLifeCycle.MOUNTED;
- },
-
- /**
- * Sets a subset of the props.
- *
- * @param {object} partialProps Subset of the next props.
- * @param {?function} callback Called after props are updated.
- * @final
- * @public
- */
- setProps: function(partialProps, callback) {
- // Merge with the pending descriptor if it exists, otherwise with existing
- // descriptor props.
- var descriptor = this._pendingDescriptor || this._descriptor;
- this.replaceProps(
- merge(descriptor.props, partialProps),
- callback
- );
- },
-
- /**
- * Replaces all of the props.
- *
- * @param {object} props New props.
- * @param {?function} callback Called after props are updated.
- * @final
- * @public
- */
- replaceProps: function(props, callback) {
- ("production" !== "development" ? invariant(
- this.isMounted(),
- 'replaceProps(...): Can only update a mounted component.'
- ) : invariant(this.isMounted()));
- ("production" !== "development" ? invariant(
- this._mountDepth === 0,
- 'replaceProps(...): You called `setProps` or `replaceProps` on a ' +
- 'component with a parent. This is an anti-pattern since props will ' +
- 'get reactively updated when rendered. Instead, change the owner\'s ' +
- '`render` method to pass the correct value as props to the component ' +
- 'where it is created.'
- ) : invariant(this._mountDepth === 0));
- // This is a deoptimized path. We optimize for always having a descriptor.
- // This creates an extra internal descriptor.
- this._pendingDescriptor = ReactDescriptor.cloneAndReplaceProps(
- this._pendingDescriptor || this._descriptor,
- props
- );
- ReactUpdates.enqueueUpdate(this, callback);
- },
-
- /**
- * Schedule a partial update to the props. Only used for internal testing.
- *
- * @param {object} partialProps Subset of the next props.
- * @param {?function} callback Called after props are updated.
- * @final
- * @internal
- */
- _setPropsInternal: function(partialProps, callback) {
- // This is a deoptimized path. We optimize for always having a descriptor.
- // This creates an extra internal descriptor.
- var descriptor = this._pendingDescriptor || this._descriptor;
- this._pendingDescriptor = ReactDescriptor.cloneAndReplaceProps(
- descriptor,
- merge(descriptor.props, partialProps)
- );
- ReactUpdates.enqueueUpdate(this, callback);
- },
-
- /**
- * Base constructor for all React components.
- *
- * Subclasses that override this method should make sure to invoke
- * `ReactComponent.Mixin.construct.call(this, ...)`.
- *
- * @param {ReactDescriptor} descriptor
- * @internal
- */
- construct: function(descriptor) {
- // This is the public exposed props object after it has been processed
- // with default props. The descriptor's props represents the true internal
- // state of the props.
- this.props = descriptor.props;
- // Record the component responsible for creating this component.
- // This is accessible through the descriptor but we maintain an extra
- // field for compatibility with devtools and as a way to make an
- // incremental update. TODO: Consider deprecating this field.
- this._owner = descriptor._owner;
-
- // All components start unmounted.
- this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
-
- // See ReactUpdates.
- this._pendingCallbacks = null;
-
- // We keep the old descriptor and a reference to the pending descriptor
- // to track updates.
- this._descriptor = descriptor;
- this._pendingDescriptor = null;
- },
-
- /**
- * Initializes the component, renders markup, and registers event listeners.
- *
- * NOTE: This does not insert any nodes into the DOM.
- *
- * Subclasses that override this method should make sure to invoke
- * `ReactComponent.Mixin.mountComponent.call(this, ...)`.
- *
- * @param {string} rootID DOM ID of the root node.
- * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
- * @param {number} mountDepth number of components in the owner hierarchy.
- * @return {?string} Rendered markup to be inserted into the DOM.
- * @internal
- */
- mountComponent: function(rootID, transaction, mountDepth) {
- ("production" !== "development" ? invariant(
- !this.isMounted(),
- 'mountComponent(%s, ...): Can only mount an unmounted component. ' +
- 'Make sure to avoid storing components between renders or reusing a ' +
- 'single component instance in multiple places.',
- rootID
- ) : invariant(!this.isMounted()));
- var props = this._descriptor.props;
- if (props.ref != null) {
- var owner = this._descriptor._owner;
- ReactOwner.addComponentAsRefTo(this, props.ref, owner);
- }
- this._rootNodeID = rootID;
- this._lifeCycleState = ComponentLifeCycle.MOUNTED;
- this._mountDepth = mountDepth;
- // Effectively: return '';
- },
-
- /**
- * Releases any resources allocated by `mountComponent`.
- *
- * NOTE: This does not remove any nodes from the DOM.
- *
- * Subclasses that override this method should make sure to invoke
- * `ReactComponent.Mixin.unmountComponent.call(this)`.
- *
- * @internal
- */
- unmountComponent: function() {
- ("production" !== "development" ? invariant(
- this.isMounted(),
- 'unmountComponent(): Can only unmount a mounted component.'
- ) : invariant(this.isMounted()));
- var props = this.props;
- if (props.ref != null) {
- ReactOwner.removeComponentAsRefFrom(this, props.ref, this._owner);
- }
- unmountIDFromEnvironment(this._rootNodeID);
- this._rootNodeID = null;
- this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
- },
-
- /**
- * Given a new instance of this component, updates the rendered DOM nodes
- * as if that instance was rendered instead.
- *
- * Subclasses that override this method should make sure to invoke
- * `ReactComponent.Mixin.receiveComponent.call(this, ...)`.
- *
- * @param {object} nextComponent Next set of properties.
- * @param {ReactReconcileTransaction} transaction
- * @internal
- */
- receiveComponent: function(nextDescriptor, transaction) {
- ("production" !== "development" ? invariant(
- this.isMounted(),
- 'receiveComponent(...): Can only update a mounted component.'
- ) : invariant(this.isMounted()));
- this._pendingDescriptor = nextDescriptor;
- this.performUpdateIfNecessary(transaction);
- },
-
- /**
- * If `_pendingDescriptor` is set, update the component.
- *
- * @param {ReactReconcileTransaction} transaction
- * @internal
- */
- performUpdateIfNecessary: function(transaction) {
- if (this._pendingDescriptor == null) {
- return;
- }
- var prevDescriptor = this._descriptor;
- var nextDescriptor = this._pendingDescriptor;
- this._descriptor = nextDescriptor;
- this.props = nextDescriptor.props;
- this._owner = nextDescriptor._owner;
- this._pendingDescriptor = null;
- this.updateComponent(transaction, prevDescriptor);
- },
-
- /**
- * Updates the component's currently mounted representation.
- *
- * @param {ReactReconcileTransaction} transaction
- * @param {object} prevDescriptor
- * @internal
- */
- updateComponent: function(transaction, prevDescriptor) {
- var nextDescriptor = this._descriptor;
-
- // If either the owner or a `ref` has changed, make sure the newest owner
- // has stored a reference to `this`, and the previous owner (if different)
- // has forgotten the reference to `this`. We use the descriptor instead
- // of the public this.props because the post processing cannot determine
- // a ref. The ref conceptually lives on the descriptor.
-
- // TODO: Should this even be possible? The owner cannot change because
- // it's forbidden by shouldUpdateReactComponent. The ref can change
- // if you swap the keys of but not the refs. Reconsider where this check
- // is made. It probably belongs where the key checking and
- // instantiateReactComponent is done.
-
- if (nextDescriptor._owner !== prevDescriptor._owner ||
- nextDescriptor.props.ref !== prevDescriptor.props.ref) {
- if (prevDescriptor.props.ref != null) {
- ReactOwner.removeComponentAsRefFrom(
- this, prevDescriptor.props.ref, prevDescriptor._owner
- );
- }
- // Correct, even if the owner is the same, and only the ref has changed.
- if (nextDescriptor.props.ref != null) {
- ReactOwner.addComponentAsRefTo(
- this,
- nextDescriptor.props.ref,
- nextDescriptor._owner
- );
- }
- }
- },
-
- /**
- * Mounts this component and inserts it into the DOM.
- *
- * @param {string} rootID DOM ID of the root node.
- * @param {DOMElement} container DOM element to mount into.
- * @param {boolean} shouldReuseMarkup If true, do not insert markup
- * @final
- * @internal
- * @see {ReactMount.renderComponent}
- */
- mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) {
- var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
- transaction.perform(
- this._mountComponentIntoNode,
- this,
- rootID,
- container,
- transaction,
- shouldReuseMarkup
- );
- ReactUpdates.ReactReconcileTransaction.release(transaction);
- },
-
- /**
- * @param {string} rootID DOM ID of the root node.
- * @param {DOMElement} container DOM element to mount into.
- * @param {ReactReconcileTransaction} transaction
- * @param {boolean} shouldReuseMarkup If true, do not insert markup
- * @final
- * @private
- */
- _mountComponentIntoNode: function(
- rootID,
- container,
- transaction,
- shouldReuseMarkup) {
- var markup = this.mountComponent(rootID, transaction, 0);
- mountImageIntoNode(markup, container, shouldReuseMarkup);
- },
-
- /**
- * Checks if this component is owned by the supplied `owner` component.
- *
- * @param {ReactComponent} owner Component to check.
- * @return {boolean} True if `owners` owns this component.
- * @final
- * @internal
- */
- isOwnedBy: function(owner) {
- return this._owner === owner;
- },
-
- /**
- * Gets another component, that shares the same owner as this one, by ref.
- *
- * @param {string} ref of a sibling Component.
- * @return {?ReactComponent} the actual sibling Component.
- * @final
- * @internal
- */
- getSiblingByRef: function(ref) {
- var owner = this._owner;
- if (!owner || !owner.refs) {
- return null;
- }
- return owner.refs[ref];
- }
- }
-};
-
-module.exports = ReactComponent;
-
-},{"./ReactDescriptor":51,"./ReactOwner":64,"./ReactUpdates":76,"./invariant":120,"./keyMirror":126,"./merge":130}],32:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactComponentBrowserEnvironment
- */
-
-/*jslint evil: true */
-
-"use strict";
-
-var ReactDOMIDOperations = _dereq_("./ReactDOMIDOperations");
-var ReactMarkupChecksum = _dereq_("./ReactMarkupChecksum");
-var ReactMount = _dereq_("./ReactMount");
-var ReactPerf = _dereq_("./ReactPerf");
-var ReactReconcileTransaction = _dereq_("./ReactReconcileTransaction");
-
-var getReactRootElementInContainer = _dereq_("./getReactRootElementInContainer");
-var invariant = _dereq_("./invariant");
-var setInnerHTML = _dereq_("./setInnerHTML");
-
-
-var ELEMENT_NODE_TYPE = 1;
-var DOC_NODE_TYPE = 9;
-
-
-/**
- * Abstracts away all functionality of `ReactComponent` requires knowledge of
- * the browser context.
- */
-var ReactComponentBrowserEnvironment = {
- ReactReconcileTransaction: ReactReconcileTransaction,
-
- BackendIDOperations: ReactDOMIDOperations,
-
- /**
- * If a particular environment requires that some resources be cleaned up,
- * specify this in the injected Mixin. In the DOM, we would likely want to
- * purge any cached node ID lookups.
- *
- * @private
- */
- unmountIDFromEnvironment: function(rootNodeID) {
- ReactMount.purgeID(rootNodeID);
- },
-
- /**
- * @param {string} markup Markup string to place into the DOM Element.
- * @param {DOMElement} container DOM Element to insert markup into.
- * @param {boolean} shouldReuseMarkup Should reuse the existing markup in the
- * container if possible.
- */
- mountImageIntoNode: ReactPerf.measure(
- 'ReactComponentBrowserEnvironment',
- 'mountImageIntoNode',
- function(markup, container, shouldReuseMarkup) {
- ("production" !== "development" ? invariant(
- container && (
- container.nodeType === ELEMENT_NODE_TYPE ||
- container.nodeType === DOC_NODE_TYPE
- ),
- 'mountComponentIntoNode(...): Target container is not valid.'
- ) : invariant(container && (
- container.nodeType === ELEMENT_NODE_TYPE ||
- container.nodeType === DOC_NODE_TYPE
- )));
-
- if (shouldReuseMarkup) {
- if (ReactMarkupChecksum.canReuseMarkup(
- markup,
- getReactRootElementInContainer(container))) {
- return;
- } else {
- ("production" !== "development" ? invariant(
- container.nodeType !== DOC_NODE_TYPE,
- 'You\'re trying to render a component to the document using ' +
- 'server rendering but the checksum was invalid. This usually ' +
- 'means you rendered a different component type or props on ' +
- 'the client from the one on the server, or your render() ' +
- 'methods are impure. React cannot handle this case due to ' +
- 'cross-browser quirks by rendering at the document root. You ' +
- 'should look for environment dependent code in your components ' +
- 'and ensure the props are the same client and server side.'
- ) : invariant(container.nodeType !== DOC_NODE_TYPE));
-
- if ("production" !== "development") {
- console.warn(
- 'React attempted to use reuse markup in a container but the ' +
- 'checksum was invalid. This generally means that you are ' +
- 'using server rendering and the markup generated on the ' +
- 'server was not what the client was expecting. React injected ' +
- 'new markup to compensate which works but you have lost many ' +
- 'of the benefits of server rendering. Instead, figure out ' +
- 'why the markup being generated is different on the client ' +
- 'or server.'
- );
- }
- }
- }
-
- ("production" !== "development" ? invariant(
- container.nodeType !== DOC_NODE_TYPE,
- 'You\'re trying to render a component to the document but ' +
- 'you didn\'t use server rendering. We can\'t do this ' +
- 'without using server rendering due to cross-browser quirks. ' +
- 'See renderComponentToString() for server rendering.'
- ) : invariant(container.nodeType !== DOC_NODE_TYPE));
-
- setInnerHTML(container, markup);
- }
- )
-};
-
-module.exports = ReactComponentBrowserEnvironment;
-
-},{"./ReactDOMIDOperations":40,"./ReactMarkupChecksum":60,"./ReactMount":61,"./ReactPerf":65,"./ReactReconcileTransaction":71,"./getReactRootElementInContainer":114,"./invariant":120,"./setInnerHTML":138}],33:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactCompositeComponent
- */
-
-"use strict";
-
-var ReactComponent = _dereq_("./ReactComponent");
-var ReactContext = _dereq_("./ReactContext");
-var ReactCurrentOwner = _dereq_("./ReactCurrentOwner");
-var ReactDescriptor = _dereq_("./ReactDescriptor");
-var ReactDescriptorValidator = _dereq_("./ReactDescriptorValidator");
-var ReactEmptyComponent = _dereq_("./ReactEmptyComponent");
-var ReactErrorUtils = _dereq_("./ReactErrorUtils");
-var ReactOwner = _dereq_("./ReactOwner");
-var ReactPerf = _dereq_("./ReactPerf");
-var ReactPropTransferer = _dereq_("./ReactPropTransferer");
-var ReactPropTypeLocations = _dereq_("./ReactPropTypeLocations");
-var ReactPropTypeLocationNames = _dereq_("./ReactPropTypeLocationNames");
-var ReactUpdates = _dereq_("./ReactUpdates");
-
-var instantiateReactComponent = _dereq_("./instantiateReactComponent");
-var invariant = _dereq_("./invariant");
-var keyMirror = _dereq_("./keyMirror");
-var merge = _dereq_("./merge");
-var mixInto = _dereq_("./mixInto");
-var monitorCodeUse = _dereq_("./monitorCodeUse");
-var mapObject = _dereq_("./mapObject");
-var shouldUpdateReactComponent = _dereq_("./shouldUpdateReactComponent");
-var warning = _dereq_("./warning");
-
-/**
- * Policies that describe methods in `ReactCompositeComponentInterface`.
- */
-var SpecPolicy = keyMirror({
- /**
- * These methods may be defined only once by the class specification or mixin.
- */
- DEFINE_ONCE: null,
- /**
- * These methods may be defined by both the class specification and mixins.
- * Subsequent definitions will be chained. These methods must return void.
- */
- DEFINE_MANY: null,
- /**
- * These methods are overriding the base ReactCompositeComponent class.
- */
- OVERRIDE_BASE: null,
- /**
- * These methods are similar to DEFINE_MANY, except we assume they return
- * objects. We try to merge the keys of the return values of all the mixed in
- * functions. If there is a key conflict we throw.
- */
- DEFINE_MANY_MERGED: null
-});
-
-
-var injectedMixins = [];
-
-/**
- * Composite components are higher-level components that compose other composite
- * or native components.
- *
- * To create a new type of `ReactCompositeComponent`, pass a specification of
- * your new class to `React.createClass`. The only requirement of your class
- * specification is that you implement a `render` method.
- *
- * var MyComponent = React.createClass({
- * render: function() {
- * return <div>Hello World</div>;
- * }
- * });
- *
- * The class specification supports a specific protocol of methods that have
- * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for
- * more the comprehensive protocol. Any other properties and methods in the
- * class specification will available on the prototype.
- *
- * @interface ReactCompositeComponentInterface
- * @internal
- */
-var ReactCompositeComponentInterface = {
-
- /**
- * An array of Mixin objects to include when defining your component.
- *
- * @type {array}
- * @optional
- */
- mixins: SpecPolicy.DEFINE_MANY,
-
- /**
- * An object containing properties and methods that should be defined on
- * the component's constructor instead of its prototype (static methods).
- *
- * @type {object}
- * @optional
- */
- statics: SpecPolicy.DEFINE_MANY,
-
- /**
- * Definition of prop types for this component.
- *
- * @type {object}
- * @optional
- */
- propTypes: SpecPolicy.DEFINE_MANY,
-
- /**
- * Definition of context types for this component.
- *
- * @type {object}
- * @optional
- */
- contextTypes: SpecPolicy.DEFINE_MANY,
-
- /**
- * Definition of context types this component sets for its children.
- *
- * @type {object}
- * @optional
- */
- childContextTypes: SpecPolicy.DEFINE_MANY,
-
- // ==== Definition methods ====
-
- /**
- * Invoked when the component is mounted. Values in the mapping will be set on
- * `this.props` if that prop is not specified (i.e. using an `in` check).
- *
- * This method is invoked before `getInitialState` and therefore cannot rely
- * on `this.state` or use `this.setState`.
- *
- * @return {object}
- * @optional
- */
- getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED,
-
- /**
- * Invoked once before the component is mounted. The return value will be used
- * as the initial value of `this.state`.
- *
- * getInitialState: function() {
- * return {
- * isOn: false,
- * fooBaz: new BazFoo()
- * }
- * }
- *
- * @return {object}
- * @optional
- */
- getInitialState: SpecPolicy.DEFINE_MANY_MERGED,
-
- /**
- * @return {object}
- * @optional
- */
- getChildContext: SpecPolicy.DEFINE_MANY_MERGED,
-
- /**
- * Uses props from `this.props` and state from `this.state` to render the
- * structure of the component.
- *
- * No guarantees are made about when or how often this method is invoked, so
- * it must not have side effects.
- *
- * render: function() {
- * var name = this.props.name;
- * return <div>Hello, {name}!</div>;
- * }
- *
- * @return {ReactComponent}
- * @nosideeffects
- * @required
- */
- render: SpecPolicy.DEFINE_ONCE,
-
-
-
- // ==== Delegate methods ====
-
- /**
- * Invoked when the component is initially created and about to be mounted.
- * This may have side effects, but any external subscriptions or data created
- * by this method must be cleaned up in `componentWillUnmount`.
- *
- * @optional
- */
- componentWillMount: SpecPolicy.DEFINE_MANY,
-
- /**
- * Invoked when the component has been mounted and has a DOM representation.
- * However, there is no guarantee that the DOM node is in the document.
- *
- * Use this as an opportunity to operate on the DOM when the component has
- * been mounted (initialized and rendered) for the first time.
- *
- * @param {DOMElement} rootNode DOM element representing the component.
- * @optional
- */
- componentDidMount: SpecPolicy.DEFINE_MANY,
-
- /**
- * Invoked before the component receives new props.
- *
- * Use this as an opportunity to react to a prop transition by updating the
- * state using `this.setState`. Current props are accessed via `this.props`.
- *
- * componentWillReceiveProps: function(nextProps, nextContext) {
- * this.setState({
- * likesIncreasing: nextProps.likeCount > this.props.likeCount
- * });
- * }
- *
- * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
- * transition may cause a state change, but the opposite is not true. If you
- * need it, you are probably looking for `componentWillUpdate`.
- *
- * @param {object} nextProps
- * @optional
- */
- componentWillReceiveProps: SpecPolicy.DEFINE_MANY,
-
- /**
- * Invoked while deciding if the component should be updated as a result of
- * receiving new props, state and/or context.
- *
- * Use this as an opportunity to `return false` when you're certain that the
- * transition to the new props/state/context will not require a component
- * update.
- *
- * shouldComponentUpdate: function(nextProps, nextState, nextContext) {
- * return !equal(nextProps, this.props) ||
- * !equal(nextState, this.state) ||
- * !equal(nextContext, this.context);
- * }
- *
- * @param {object} nextProps
- * @param {?object} nextState
- * @param {?object} nextContext
- * @return {boolean} True if the component should update.
- * @optional
- */
- shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,
-
- /**
- * Invoked when the component is about to update due to a transition from
- * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState`
- * and `nextContext`.
- *
- * Use this as an opportunity to perform preparation before an update occurs.
- *
- * NOTE: You **cannot** use `this.setState()` in this method.
- *
- * @param {object} nextProps
- * @param {?object} nextState
- * @param {?object} nextContext
- * @param {ReactReconcileTransaction} transaction
- * @optional
- */
- componentWillUpdate: SpecPolicy.DEFINE_MANY,
-
- /**
- * Invoked when the component's DOM representation has been updated.
- *
- * Use this as an opportunity to operate on the DOM when the component has
- * been updated.
- *
- * @param {object} prevProps
- * @param {?object} prevState
- * @param {?object} prevContext
- * @param {DOMElement} rootNode DOM element representing the component.
- * @optional
- */
- componentDidUpdate: SpecPolicy.DEFINE_MANY,
-
- /**
- * Invoked when the component is about to be removed from its parent and have
- * its DOM representation destroyed.
- *
- * Use this as an opportunity to deallocate any external resources.
- *
- * NOTE: There is no `componentDidUnmount` since your component will have been
- * destroyed by that point.
- *
- * @optional
- */
- componentWillUnmount: SpecPolicy.DEFINE_MANY,
-
-
-
- // ==== Advanced methods ====
-
- /**
- * Updates the component's currently mounted DOM representation.
- *
- * By default, this implements React's rendering and reconciliation algorithm.
- * Sophisticated clients may wish to override this.
- *
- * @param {ReactReconcileTransaction} transaction
- * @internal
- * @overridable
- */
- updateComponent: SpecPolicy.OVERRIDE_BASE
-
-};
-
-/**
- * Mapping from class specification keys to special processing functions.
- *
- * Although these are declared like instance properties in the specification
- * when defining classes using `React.createClass`, they are actually static
- * and are accessible on the constructor instead of the prototype. Despite
- * being static, they must be defined outside of the "statics" key under
- * which all other static methods are defined.
- */
-var RESERVED_SPEC_KEYS = {
- displayName: function(Constructor, displayName) {
- Constructor.displayName = displayName;
- },
- mixins: function(Constructor, mixins) {
- if (mixins) {
- for (var i = 0; i < mixins.length; i++) {
- mixSpecIntoComponent(Constructor, mixins[i]);
- }
- }
- },
- childContextTypes: function(Constructor, childContextTypes) {
- validateTypeDef(
- Constructor,
- childContextTypes,
- ReactPropTypeLocations.childContext
- );
- Constructor.childContextTypes = merge(
- Constructor.childContextTypes,
- childContextTypes
- );
- },
- contextTypes: function(Constructor, contextTypes) {
- validateTypeDef(
- Constructor,
- contextTypes,
- ReactPropTypeLocations.context
- );
- Constructor.contextTypes = merge(Constructor.contextTypes, contextTypes);
- },
- /**
- * Special case getDefaultProps which should move into statics but requires
- * automatic merging.
- */
- getDefaultProps: function(Constructor, getDefaultProps) {
- if (Constructor.getDefaultProps) {
- Constructor.getDefaultProps = createMergedResultFunction(
- Constructor.getDefaultProps,
- getDefaultProps
- );
- } else {
- Constructor.getDefaultProps = getDefaultProps;
- }
- },
- propTypes: function(Constructor, propTypes) {
- validateTypeDef(
- Constructor,
- propTypes,
- ReactPropTypeLocations.prop
- );
- Constructor.propTypes = merge(Constructor.propTypes, propTypes);
- },
- statics: function(Constructor, statics) {
- mixStaticSpecIntoComponent(Constructor, statics);
- }
-};
-
-function getDeclarationErrorAddendum(component) {
- var owner = component._owner || null;
- if (owner && owner.constructor && owner.constructor.displayName) {
- return ' Check the render method of `' + owner.constructor.displayName +
- '`.';
- }
- return '';
-}
-
-function validateTypeDef(Constructor, typeDef, location) {
- for (var propName in typeDef) {
- if (typeDef.hasOwnProperty(propName)) {
- ("production" !== "development" ? invariant(
- typeof typeDef[propName] == 'function',
- '%s: %s type `%s` is invalid; it must be a function, usually from ' +
- 'React.PropTypes.',
- Constructor.displayName || 'ReactCompositeComponent',
- ReactPropTypeLocationNames[location],
- propName
- ) : invariant(typeof typeDef[propName] == 'function'));
- }
- }
-}
-
-function validateMethodOverride(proto, name) {
- var specPolicy = ReactCompositeComponentInterface.hasOwnProperty(name) ?
- ReactCompositeComponentInterface[name] :
- null;
-
- // Disallow overriding of base class methods unless explicitly allowed.
- if (ReactCompositeComponentMixin.hasOwnProperty(name)) {
- ("production" !== "development" ? invariant(
- specPolicy === SpecPolicy.OVERRIDE_BASE,
- 'ReactCompositeComponentInterface: You are attempting to override ' +
- '`%s` from your class specification. Ensure that your method names ' +
- 'do not overlap with React methods.',
- name
- ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE));
- }
-
- // Disallow defining methods more than once unless explicitly allowed.
- if (proto.hasOwnProperty(name)) {
- ("production" !== "development" ? invariant(
- specPolicy === SpecPolicy.DEFINE_MANY ||
- specPolicy === SpecPolicy.DEFINE_MANY_MERGED,
- 'ReactCompositeComponentInterface: You are attempting to define ' +
- '`%s` on your component more than once. This conflict may be due ' +
- 'to a mixin.',
- name
- ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY ||
- specPolicy === SpecPolicy.DEFINE_MANY_MERGED));
- }
-}
-
-function validateLifeCycleOnReplaceState(instance) {
- var compositeLifeCycleState = instance._compositeLifeCycleState;
- ("production" !== "development" ? invariant(
- instance.isMounted() ||
- compositeLifeCycleState === CompositeLifeCycle.MOUNTING,
- 'replaceState(...): Can only update a mounted or mounting component.'
- ) : invariant(instance.isMounted() ||
- compositeLifeCycleState === CompositeLifeCycle.MOUNTING));
- ("production" !== "development" ? invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE,
- 'replaceState(...): Cannot update during an existing state transition ' +
- '(such as within `render`). This could potentially cause an infinite ' +
- 'loop so it is forbidden.'
- ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE));
- ("production" !== "development" ? invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
- 'replaceState(...): Cannot update while unmounting component. This ' +
- 'usually means you called setState() on an unmounted component.'
- ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING));
-}
-
-/**
- * Custom version of `mixInto` which handles policy validation and reserved
- * specification keys when building `ReactCompositeComponent` classses.
- */
-function mixSpecIntoComponent(Constructor, spec) {
- ("production" !== "development" ? invariant(
- !ReactDescriptor.isValidFactory(spec),
- 'ReactCompositeComponent: You\'re attempting to ' +
- 'use a component class as a mixin. Instead, just use a regular object.'
- ) : invariant(!ReactDescriptor.isValidFactory(spec)));
- ("production" !== "development" ? invariant(
- !ReactDescriptor.isValidDescriptor(spec),
- 'ReactCompositeComponent: You\'re attempting to ' +
- 'use a component as a mixin. Instead, just use a regular object.'
- ) : invariant(!ReactDescriptor.isValidDescriptor(spec)));
-
- var proto = Constructor.prototype;
- for (var name in spec) {
- var property = spec[name];
- if (!spec.hasOwnProperty(name)) {
- continue;
- }
-
- validateMethodOverride(proto, name);
-
- if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
- RESERVED_SPEC_KEYS[name](Constructor, property);
- } else {
- // Setup methods on prototype:
- // The following member methods should not be automatically bound:
- // 1. Expected ReactCompositeComponent methods (in the "interface").
- // 2. Overridden methods (that were mixed in).
- var isCompositeComponentMethod =
- ReactCompositeComponentInterface.hasOwnProperty(name);
- var isAlreadyDefined = proto.hasOwnProperty(name);
- var markedDontBind = property && property.__reactDontBind;
- var isFunction = typeof property === 'function';
- var shouldAutoBind =
- isFunction &&
- !isCompositeComponentMethod &&
- !isAlreadyDefined &&
- !markedDontBind;
-
- if (shouldAutoBind) {
- if (!proto.__reactAutoBindMap) {
- proto.__reactAutoBindMap = {};
- }
- proto.__reactAutoBindMap[name] = property;
- proto[name] = property;
- } else {
- if (isAlreadyDefined) {
- var specPolicy = ReactCompositeComponentInterface[name];
-
- // These cases should already be caught by validateMethodOverride
- ("production" !== "development" ? invariant(
- isCompositeComponentMethod && (
- specPolicy === SpecPolicy.DEFINE_MANY_MERGED ||
- specPolicy === SpecPolicy.DEFINE_MANY
- ),
- 'ReactCompositeComponent: Unexpected spec policy %s for key %s ' +
- 'when mixing in component specs.',
- specPolicy,
- name
- ) : invariant(isCompositeComponentMethod && (
- specPolicy === SpecPolicy.DEFINE_MANY_MERGED ||
- specPolicy === SpecPolicy.DEFINE_MANY
- )));
-
- // For methods which are defined more than once, call the existing
- // methods before calling the new property, merging if appropriate.
- if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) {
- proto[name] = createMergedResultFunction(proto[name], property);
- } else if (specPolicy === SpecPolicy.DEFINE_MANY) {
- proto[name] = createChainedFunction(proto[name], property);
- }
- } else {
- proto[name] = property;
- if ("production" !== "development") {
- // Add verbose displayName to the function, which helps when looking
- // at profiling tools.
- if (typeof property === 'function' && spec.displayName) {
- proto[name].displayName = spec.displayName + '_' + name;
- }
- }
- }
- }
- }
- }
-}
-
-function mixStaticSpecIntoComponent(Constructor, statics) {
- if (!statics) {
- return;
- }
- for (var name in statics) {
- var property = statics[name];
- if (!statics.hasOwnProperty(name)) {
- continue;
- }
-
- var isInherited = name in Constructor;
- var result = property;
- if (isInherited) {
- var existingProperty = Constructor[name];
- var existingType = typeof existingProperty;
- var propertyType = typeof property;
- ("production" !== "development" ? invariant(
- existingType === 'function' && propertyType === 'function',
- 'ReactCompositeComponent: You are attempting to define ' +
- '`%s` on your component more than once, but that is only supported ' +
- 'for functions, which are chained together. This conflict may be ' +
- 'due to a mixin.',
- name
- ) : invariant(existingType === 'function' && propertyType === 'function'));
- result = createChainedFunction(existingProperty, property);
- }
- Constructor[name] = result;
- }
-}
-
-/**
- * Merge two objects, but throw if both contain the same key.
- *
- * @param {object} one The first object, which is mutated.
- * @param {object} two The second object
- * @return {object} one after it has been mutated to contain everything in two.
- */
-function mergeObjectsWithNoDuplicateKeys(one, two) {
- ("production" !== "development" ? invariant(
- one && two && typeof one === 'object' && typeof two === 'object',
- 'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects'
- ) : invariant(one && two && typeof one === 'object' && typeof two === 'object'));
-
- mapObject(two, function(value, key) {
- ("production" !== "development" ? invariant(
- one[key] === undefined,
- 'mergeObjectsWithNoDuplicateKeys(): ' +
- 'Tried to merge two objects with the same key: %s',
- key
- ) : invariant(one[key] === undefined));
- one[key] = value;
- });
- return one;
-}
-
-/**
- * Creates a function that invokes two functions and merges their return values.
- *
- * @param {function} one Function to invoke first.
- * @param {function} two Function to invoke second.
- * @return {function} Function that invokes the two argument functions.
- * @private
- */
-function createMergedResultFunction(one, two) {
- return function mergedResult() {
- var a = one.apply(this, arguments);
- var b = two.apply(this, arguments);
- if (a == null) {
- return b;
- } else if (b == null) {
- return a;
- }
- return mergeObjectsWithNoDuplicateKeys(a, b);
- };
-}
-
-/**
- * Creates a function that invokes two functions and ignores their return vales.
- *
- * @param {function} one Function to invoke first.
- * @param {function} two Function to invoke second.
- * @return {function} Function that invokes the two argument functions.
- * @private
- */
-function createChainedFunction(one, two) {
- return function chainedFunction() {
- one.apply(this, arguments);
- two.apply(this, arguments);
- };
-}
-
-/**
- * `ReactCompositeComponent` maintains an auxiliary life cycle state in
- * `this._compositeLifeCycleState` (which can be null).
- *
- * This is different from the life cycle state maintained by `ReactComponent` in
- * `this._lifeCycleState`. The following diagram shows how the states overlap in
- * time. There are times when the CompositeLifeCycle is null - at those times it
- * is only meaningful to look at ComponentLifeCycle alone.
- *
- * Top Row: ReactComponent.ComponentLifeCycle
- * Low Row: ReactComponent.CompositeLifeCycle
- *
- * +-------+------------------------------------------------------+--------+
- * | UN | MOUNTED | UN |
- * |MOUNTED| | MOUNTED|
- * +-------+------------------------------------------------------+--------+
- * | ^--------+ +------+ +------+ +------+ +--------^ |
- * | | | | | | | | | | | |
- * | 0--|MOUNTING|-0-|RECEIV|-0-|RECEIV|-0-|RECEIV|-0-| UN |--->0 |
- * | | | |PROPS | | PROPS| | STATE| |MOUNTING| |
- * | | | | | | | | | | | |
- * | | | | | | | | | | | |
- * | +--------+ +------+ +------+ +------+ +--------+ |
- * | | | |
- * +-------+------------------------------------------------------+--------+
- */
-var CompositeLifeCycle = keyMirror({
- /**
- * Components in the process of being mounted respond to state changes
- * differently.
- */
- MOUNTING: null,
- /**
- * Components in the process of being unmounted are guarded against state
- * changes.
- */
- UNMOUNTING: null,
- /**
- * Components that are mounted and receiving new props respond to state
- * changes differently.
- */
- RECEIVING_PROPS: null,
- /**
- * Components that are mounted and receiving new state are guarded against
- * additional state changes.
- */
- RECEIVING_STATE: null
-});
-
-/**
- * @lends {ReactCompositeComponent.prototype}
- */
-var ReactCompositeComponentMixin = {
-
- /**
- * Base constructor for all composite component.
- *
- * @param {ReactDescriptor} descriptor
- * @final
- * @internal
- */
- construct: function(descriptor) {
- // Children can be either an array or more than one argument
- ReactComponent.Mixin.construct.apply(this, arguments);
- ReactOwner.Mixin.construct.apply(this, arguments);
-
- this.state = null;
- this._pendingState = null;
-
- // This is the public post-processed context. The real context and pending
- // context lives on the descriptor.
- this.context = null;
-
- this._compositeLifeCycleState = null;
- },
-
- /**
- * Checks whether or not this composite component is mounted.
- * @return {boolean} True if mounted, false otherwise.
- * @protected
- * @final
- */
- isMounted: function() {
- return ReactComponent.Mixin.isMounted.call(this) &&
- this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING;
- },
-
- /**
- * Initializes the component, renders markup, and registers event listeners.
- *
- * @param {string} rootID DOM ID of the root node.
- * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
- * @param {number} mountDepth number of components in the owner hierarchy
- * @return {?string} Rendered markup to be inserted into the DOM.
- * @final
- * @internal
- */
- mountComponent: ReactPerf.measure(
- 'ReactCompositeComponent',
- 'mountComponent',
- function(rootID, transaction, mountDepth) {
- ReactComponent.Mixin.mountComponent.call(
- this,
- rootID,
- transaction,
- mountDepth
- );
- this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
-
- if (this.__reactAutoBindMap) {
- this._bindAutoBindMethods();
- }
-
- this.context = this._processContext(this._descriptor._context);
- this.props = this._processProps(this.props);
-
- this.state = this.getInitialState ? this.getInitialState() : null;
- ("production" !== "development" ? invariant(
- typeof this.state === 'object' && !Array.isArray(this.state),
- '%s.getInitialState(): must return an object or null',
- this.constructor.displayName || 'ReactCompositeComponent'
- ) : invariant(typeof this.state === 'object' && !Array.isArray(this.state)));
-
- this._pendingState = null;
- this._pendingForceUpdate = false;
-
- if (this.componentWillMount) {
- this.componentWillMount();
- // When mounting, calls to `setState` by `componentWillMount` will set
- // `this._pendingState` without triggering a re-render.
- if (this._pendingState) {
- this.state = this._pendingState;
- this._pendingState = null;
- }
- }
-
- this._renderedComponent = instantiateReactComponent(
- this._renderValidatedComponent()
- );
-
- // Done with mounting, `setState` will now trigger UI changes.
- this._compositeLifeCycleState = null;
- var markup = this._renderedComponent.mountComponent(
- rootID,
- transaction,
- mountDepth + 1
- );
- if (this.componentDidMount) {
- transaction.getReactMountReady().enqueue(this.componentDidMount, this);
- }
- return markup;
- }
- ),
-
- /**
- * Releases any resources allocated by `mountComponent`.
- *
- * @final
- * @internal
- */
- unmountComponent: function() {
- this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING;
- if (this.componentWillUnmount) {
- this.componentWillUnmount();
- }
- this._compositeLifeCycleState = null;
-
- this._renderedComponent.unmountComponent();
- this._renderedComponent = null;
-
- ReactComponent.Mixin.unmountComponent.call(this);
-
- // Some existing components rely on this.props even after they've been
- // destroyed (in event handlers).
- // TODO: this.props = null;
- // TODO: this.state = null;
- },
-
- /**
- * Sets a subset of the state. Always use this or `replaceState` to mutate
- * state. You should treat `this.state` as immutable.
- *
- * There is no guarantee that `this.state` will be immediately updated, so
- * accessing `this.state` after calling this method may return the old value.
- *
- * There is no guarantee that calls to `setState` will run synchronously,
- * as they may eventually be batched together. You can provide an optional
- * callback that will be executed when the call to setState is actually
- * completed.
- *
- * @param {object} partialState Next partial state to be merged with state.
- * @param {?function} callback Called after state is updated.
- * @final
- * @protected
- */
- setState: function(partialState, callback) {
- ("production" !== "development" ? invariant(
- typeof partialState === 'object' || partialState == null,
- 'setState(...): takes an object of state variables to update.'
- ) : invariant(typeof partialState === 'object' || partialState == null));
- if ("production" !== "development"){
- ("production" !== "development" ? warning(
- partialState != null,
- 'setState(...): You passed an undefined or null state object; ' +
- 'instead, use forceUpdate().'
- ) : null);
- }
- // Merge with `_pendingState` if it exists, otherwise with existing state.
- this.replaceState(
- merge(this._pendingState || this.state, partialState),
- callback
- );
- },
-
- /**
- * Replaces all of the state. Always use this or `setState` to mutate state.
- * You should treat `this.state` as immutable.
- *
- * There is no guarantee that `this.state` will be immediately updated, so
- * accessing `this.state` after calling this method may return the old value.
- *
- * @param {object} completeState Next state.
- * @param {?function} callback Called after state is updated.
- * @final
- * @protected
- */
- replaceState: function(completeState, callback) {
- validateLifeCycleOnReplaceState(this);
- this._pendingState = completeState;
- if (this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING) {
- // If we're in a componentWillMount handler, don't enqueue a rerender
- // because ReactUpdates assumes we're in a browser context (which is wrong
- // for server rendering) and we're about to do a render anyway.
- // TODO: The callback here is ignored when setState is called from
- // componentWillMount. Either fix it or disallow doing so completely in
- // favor of getInitialState.
- ReactUpdates.enqueueUpdate(this, callback);
- }
- },
-
- /**
- * Filters the context object to only contain keys specified in
- * `contextTypes`, and asserts that they are valid.
- *
- * @param {object} context
- * @return {?object}
- * @private
- */
- _processContext: function(context) {
- var maskedContext = null;
- var contextTypes = this.constructor.contextTypes;
- if (contextTypes) {
- maskedContext = {};
- for (var contextName in contextTypes) {
- maskedContext[contextName] = context[contextName];
- }
- if ("production" !== "development") {
- this._checkPropTypes(
- contextTypes,
- maskedContext,
- ReactPropTypeLocations.context
- );
- }
- }
- return maskedContext;
- },
-
- /**
- * @param {object} currentContext
- * @return {object}
- * @private
- */
- _processChildContext: function(currentContext) {
- var childContext = this.getChildContext && this.getChildContext();
- var displayName = this.constructor.displayName || 'ReactCompositeComponent';
- if (childContext) {
- ("production" !== "development" ? invariant(
- typeof this.constructor.childContextTypes === 'object',
- '%s.getChildContext(): childContextTypes must be defined in order to ' +
- 'use getChildContext().',
- displayName
- ) : invariant(typeof this.constructor.childContextTypes === 'object'));
- if ("production" !== "development") {
- this._checkPropTypes(
- this.constructor.childContextTypes,
- childContext,
- ReactPropTypeLocations.childContext
- );
- }
- for (var name in childContext) {
- ("production" !== "development" ? invariant(
- name in this.constructor.childContextTypes,
- '%s.getChildContext(): key "%s" is not defined in childContextTypes.',
- displayName,
- name
- ) : invariant(name in this.constructor.childContextTypes));
- }
- return merge(currentContext, childContext);
- }
- return currentContext;
- },
-
- /**
- * Processes props by setting default values for unspecified props and
- * asserting that the props are valid. Does not mutate its argument; returns
- * a new props object with defaults merged in.
- *
- * @param {object} newProps
- * @return {object}
- * @private
- */
- _processProps: function(newProps) {
- var defaultProps = this.constructor.defaultProps;
- var props;
- if (defaultProps) {
- props = merge(newProps);
- for (var propName in defaultProps) {
- if (typeof props[propName] === 'undefined') {
- props[propName] = defaultProps[propName];
- }
- }
- } else {
- props = newProps;
- }
- if ("production" !== "development") {
- var propTypes = this.constructor.propTypes;
- if (propTypes) {
- this._checkPropTypes(propTypes, props, ReactPropTypeLocations.prop);
- }
- }
- return props;
- },
-
- /**
- * Assert that the props are valid
- *
- * @param {object} propTypes Map of prop name to a ReactPropType
- * @param {object} props
- * @param {string} location e.g. "prop", "context", "child context"
- * @private
- */
- _checkPropTypes: function(propTypes, props, location) {
- // TODO: Stop validating prop types here and only use the descriptor
- // validation.
- var componentName = this.constructor.displayName;
- for (var propName in propTypes) {
- if (propTypes.hasOwnProperty(propName)) {
- var error =
- propTypes[propName](props, propName, componentName, location);
- if (error instanceof Error) {
- // We may want to extend this logic for similar errors in
- // renderComponent calls, so I'm abstracting it away into
- // a function to minimize refactoring in the future
- var addendum = getDeclarationErrorAddendum(this);
- ("production" !== "development" ? warning(false, error.message + addendum) : null);
- }
- }
- }
- },
-
- /**
- * If any of `_pendingDescriptor`, `_pendingState`, or `_pendingForceUpdate`
- * is set, update the component.
- *
- * @param {ReactReconcileTransaction} transaction
- * @internal
- */
- performUpdateIfNecessary: function(transaction) {
- var compositeLifeCycleState = this._compositeLifeCycleState;
- // Do not trigger a state transition if we are in the middle of mounting or
- // receiving props because both of those will already be doing this.
- if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING ||
- compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) {
- return;
- }
-
- if (this._pendingDescriptor == null &&
- this._pendingState == null &&
- !this._pendingForceUpdate) {
- return;
- }
-
- var nextContext = this.context;
- var nextProps = this.props;
- var nextDescriptor = this._descriptor;
- if (this._pendingDescriptor != null) {
- nextDescriptor = this._pendingDescriptor;
- nextContext = this._processContext(nextDescriptor._context);
- nextProps = this._processProps(nextDescriptor.props);
- this._pendingDescriptor = null;
-
- this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;
- if (this.componentWillReceiveProps) {
- this.componentWillReceiveProps(nextProps, nextContext);
- }
- }
-
- this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE;
-
- var nextState = this._pendingState || this.state;
- this._pendingState = null;
-
- try {
- var shouldUpdate =
- this._pendingForceUpdate ||
- !this.shouldComponentUpdate ||
- this.shouldComponentUpdate(nextProps, nextState, nextContext);
-
- if ("production" !== "development") {
- if (typeof shouldUpdate === "undefined") {
- console.warn(
- (this.constructor.displayName || 'ReactCompositeComponent') +
- '.shouldComponentUpdate(): Returned undefined instead of a ' +
- 'boolean value. Make sure to return true or false.'
- );
- }
- }
-
- if (shouldUpdate) {
- this._pendingForceUpdate = false;
- // Will set `this.props`, `this.state` and `this.context`.
- this._performComponentUpdate(
- nextDescriptor,
- nextProps,
- nextState,
- nextContext,
- transaction
- );
- } else {
- // If it's determined that a component should not update, we still want
- // to set props and state.
- this._descriptor = nextDescriptor;
- this.props = nextProps;
- this.state = nextState;
- this.context = nextContext;
-
- // Owner cannot change because shouldUpdateReactComponent doesn't allow
- // it. TODO: Remove this._owner completely.
- this._owner = nextDescriptor._owner;
- }
- } finally {
- this._compositeLifeCycleState = null;
- }
- },
-
- /**
- * Merges new props and state, notifies delegate methods of update and
- * performs update.
- *
- * @param {ReactDescriptor} nextDescriptor Next descriptor
- * @param {object} nextProps Next public object to set as properties.
- * @param {?object} nextState Next object to set as state.
- * @param {?object} nextContext Next public object to set as context.
- * @param {ReactReconcileTransaction} transaction
- * @private
- */
- _performComponentUpdate: function(
- nextDescriptor,
- nextProps,
- nextState,
- nextContext,
- transaction
- ) {
- var prevDescriptor = this._descriptor;
- var prevProps = this.props;
- var prevState = this.state;
- var prevContext = this.context;
-
- if (this.componentWillUpdate) {
- this.componentWillUpdate(nextProps, nextState, nextContext);
- }
-
- this._descriptor = nextDescriptor;
- this.props = nextProps;
- this.state = nextState;
- this.context = nextContext;
-
- // Owner cannot change because shouldUpdateReactComponent doesn't allow
- // it. TODO: Remove this._owner completely.
- this._owner = nextDescriptor._owner;
-
- this.updateComponent(
- transaction,
- prevDescriptor
- );
-
- if (this.componentDidUpdate) {
- transaction.getReactMountReady().enqueue(
- this.componentDidUpdate.bind(this, prevProps, prevState, prevContext),
- this
- );
- }
- },
-
- receiveComponent: function(nextDescriptor, transaction) {
- if (nextDescriptor === this._descriptor &&
- nextDescriptor._owner != null) {
- // Since descriptors are immutable after the owner is rendered,
- // we can do a cheap identity compare here to determine if this is a
- // superfluous reconcile. It's possible for state to be mutable but such
- // change should trigger an update of the owner which would recreate
- // the descriptor. We explicitly check for the existence of an owner since
- // it's possible for a descriptor created outside a composite to be
- // deeply mutated and reused.
- return;
- }
-
- ReactComponent.Mixin.receiveComponent.call(
- this,
- nextDescriptor,
- transaction
- );
- },
-
- /**
- * Updates the component's currently mounted DOM representation.
- *
- * By default, this implements React's rendering and reconciliation algorithm.
- * Sophisticated clients may wish to override this.
- *
- * @param {ReactReconcileTransaction} transaction
- * @param {ReactDescriptor} prevDescriptor
- * @internal
- * @overridable
- */
- updateComponent: ReactPerf.measure(
- 'ReactCompositeComponent',
- 'updateComponent',
- function(transaction, prevParentDescriptor) {
- ReactComponent.Mixin.updateComponent.call(
- this,
- transaction,
- prevParentDescriptor
- );
-
- var prevComponentInstance = this._renderedComponent;
- var prevDescriptor = prevComponentInstance._descriptor;
- var nextDescriptor = this._renderValidatedComponent();
- if (shouldUpdateReactComponent(prevDescriptor, nextDescriptor)) {
- prevComponentInstance.receiveComponent(nextDescriptor, transaction);
- } else {
- // These two IDs are actually the same! But nothing should rely on that.
- var thisID = this._rootNodeID;
- var prevComponentID = prevComponentInstance._rootNodeID;
- prevComponentInstance.unmountComponent();
- this._renderedComponent = instantiateReactComponent(nextDescriptor);
- var nextMarkup = this._renderedComponent.mountComponent(
- thisID,
- transaction,
- this._mountDepth + 1
- );
- ReactComponent.BackendIDOperations.dangerouslyReplaceNodeWithMarkupByID(
- prevComponentID,
- nextMarkup
- );
- }
- }
- ),
-
- /**
- * Forces an update. This should only be invoked when it is known with
- * certainty that we are **not** in a DOM transaction.
- *
- * You may want to call this when you know that some deeper aspect of the
- * component's state has changed but `setState` was not called.
- *
- * This will not invoke `shouldUpdateComponent`, but it will invoke
- * `componentWillUpdate` and `componentDidUpdate`.
- *
- * @param {?function} callback Called after update is complete.
- * @final
- * @protected
- */
- forceUpdate: function(callback) {
- var compositeLifeCycleState = this._compositeLifeCycleState;
- ("production" !== "development" ? invariant(
- this.isMounted() ||
- compositeLifeCycleState === CompositeLifeCycle.MOUNTING,
- 'forceUpdate(...): Can only force an update on mounted or mounting ' +
- 'components.'
- ) : invariant(this.isMounted() ||
- compositeLifeCycleState === CompositeLifeCycle.MOUNTING));
- ("production" !== "development" ? invariant(
- compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
- compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
- 'forceUpdate(...): Cannot force an update while unmounting component ' +
- 'or during an existing state transition (such as within `render`).'
- ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
- compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING));
- this._pendingForceUpdate = true;
- ReactUpdates.enqueueUpdate(this, callback);
- },
-
- /**
- * @private
- */
- _renderValidatedComponent: ReactPerf.measure(
- 'ReactCompositeComponent',
- '_renderValidatedComponent',
- function() {
- var renderedComponent;
- var previousContext = ReactContext.current;
- ReactContext.current = this._processChildContext(
- this._descriptor._context
- );
- ReactCurrentOwner.current = this;
- try {
- renderedComponent = this.render();
- if (renderedComponent === null || renderedComponent === false) {
- renderedComponent = ReactEmptyComponent.getEmptyComponent();
- ReactEmptyComponent.registerNullComponentID(this._rootNodeID);
- } else {
- ReactEmptyComponent.deregisterNullComponentID(this._rootNodeID);
- }
- } finally {
- ReactContext.current = previousContext;
- ReactCurrentOwner.current = null;
- }
- ("production" !== "development" ? invariant(
- ReactDescriptor.isValidDescriptor(renderedComponent),
- '%s.render(): A valid ReactComponent must be returned. You may have ' +
- 'returned undefined, an array or some other invalid object.',
- this.constructor.displayName || 'ReactCompositeComponent'
- ) : invariant(ReactDescriptor.isValidDescriptor(renderedComponent)));
- return renderedComponent;
- }
- ),
-
- /**
- * @private
- */
- _bindAutoBindMethods: function() {
- for (var autoBindKey in this.__reactAutoBindMap) {
- if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {
- continue;
- }
- var method = this.__reactAutoBindMap[autoBindKey];
- this[autoBindKey] = this._bindAutoBindMethod(ReactErrorUtils.guard(
- method,
- this.constructor.displayName + '.' + autoBindKey
- ));
- }
- },
-
- /**
- * Binds a method to the component.
- *
- * @param {function} method Method to be bound.
- * @private
- */
- _bindAutoBindMethod: function(method) {
- var component = this;
- var boundMethod = function() {
- return method.apply(component, arguments);
- };
- if ("production" !== "development") {
- boundMethod.__reactBoundContext = component;
- boundMethod.__reactBoundMethod = method;
- boundMethod.__reactBoundArguments = null;
- var componentName = component.constructor.displayName;
- var _bind = boundMethod.bind;
- boundMethod.bind = function(newThis ) {var args=Array.prototype.slice.call(arguments,1);
- // User is trying to bind() an autobound method; we effectively will
- // ignore the value of "this" that the user is trying to use, so
- // let's warn.
- if (newThis !== component && newThis !== null) {
- monitorCodeUse('react_bind_warning', { component: componentName });
- console.warn(
- 'bind(): React component methods may only be bound to the ' +
- 'component instance. See ' + componentName
- );
- } else if (!args.length) {
- monitorCodeUse('react_bind_warning', { component: componentName });
- console.warn(
- 'bind(): You are binding a component method to the component. ' +
- 'React does this for you automatically in a high-performance ' +
- 'way, so you can safely remove this call. See ' + componentName
- );
- return boundMethod;
- }
- var reboundMethod = _bind.apply(boundMethod, arguments);
- reboundMethod.__reactBoundContext = component;
- reboundMethod.__reactBoundMethod = method;
- reboundMethod.__reactBoundArguments = args;
- return reboundMethod;
- };
- }
- return boundMethod;
- }
-};
-
-var ReactCompositeComponentBase = function() {};
-mixInto(ReactCompositeComponentBase, ReactComponent.Mixin);
-mixInto(ReactCompositeComponentBase, ReactOwner.Mixin);
-mixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin);
-mixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);
-
-/**
- * Module for creating composite components.
- *
- * @class ReactCompositeComponent
- * @extends ReactComponent
- * @extends ReactOwner
- * @extends ReactPropTransferer
- */
-var ReactCompositeComponent = {
-
- LifeCycle: CompositeLifeCycle,
-
- Base: ReactCompositeComponentBase,
-
- /**
- * Creates a composite component class given a class specification.
- *
- * @param {object} spec Class specification (which must define `render`).
- * @return {function} Component constructor function.
- * @public
- */
- createClass: function(spec) {
- var Constructor = function(props, owner) {
- this.construct(props, owner);
- };
- Constructor.prototype = new ReactCompositeComponentBase();
- Constructor.prototype.constructor = Constructor;
-
- injectedMixins.forEach(
- mixSpecIntoComponent.bind(null, Constructor)
- );
-
- mixSpecIntoComponent(Constructor, spec);
-
- // Initialize the defaultProps property after all mixins have been merged
- if (Constructor.getDefaultProps) {
- Constructor.defaultProps = Constructor.getDefaultProps();
- }
-
- ("production" !== "development" ? invariant(
- Constructor.prototype.render,
- 'createClass(...): Class specification must implement a `render` method.'
- ) : invariant(Constructor.prototype.render));
-
- if ("production" !== "development") {
- if (Constructor.prototype.componentShouldUpdate) {
- monitorCodeUse(
- 'react_component_should_update_warning',
- { component: spec.displayName }
- );
- console.warn(
- (spec.displayName || 'A component') + ' has a method called ' +
- 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
- 'The name is phrased as a question because the function is ' +
- 'expected to return a value.'
- );
- }
- }
-
- // Reduce time spent doing lookups by setting these on the prototype.
- for (var methodName in ReactCompositeComponentInterface) {
- if (!Constructor.prototype[methodName]) {
- Constructor.prototype[methodName] = null;
- }
- }
-
- var descriptorFactory = ReactDescriptor.createFactory(Constructor);
-
- if ("production" !== "development") {
- return ReactDescriptorValidator.createFactory(
- descriptorFactory,
- Constructor.propTypes,
- Constructor.contextTypes
- );
- }
-
- return descriptorFactory;
- },
-
- injection: {
- injectMixin: function(mixin) {
- injectedMixins.push(mixin);
- }
- }
-};
-
-module.exports = ReactCompositeComponent;
-
-},{"./ReactComponent":31,"./ReactContext":34,"./ReactCurrentOwner":35,"./ReactDescriptor":51,"./ReactDescriptorValidator":52,"./ReactEmptyComponent":53,"./ReactErrorUtils":54,"./ReactOwner":64,"./ReactPerf":65,"./ReactPropTransferer":66,"./ReactPropTypeLocationNames":67,"./ReactPropTypeLocations":68,"./ReactUpdates":76,"./instantiateReactComponent":119,"./invariant":120,"./keyMirror":126,"./mapObject":128,"./merge":130,"./mixInto":133,"./monitorCodeUse":134,"./shouldUpdateReactComponent":140,"./warning":143}],34:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactContext
- */
-
-"use strict";
-
-var merge = _dereq_("./merge");
-
-/**
- * Keeps track of the current context.
- *
- * The context is automatically passed down the component ownership hierarchy
- * and is accessible via `this.context` on ReactCompositeComponents.
- */
-var ReactContext = {
-
- /**
- * @internal
- * @type {object}
- */
- current: {},
-
- /**
- * Temporarily extends the current context while executing scopedCallback.
- *
- * A typical use case might look like
- *
- * render: function() {
- * var children = ReactContext.withContext({foo: 'foo'} () => (
- *
- * ));
- * return <div>{children}</div>;
- * }
- *
- * @param {object} newContext New context to merge into the existing context
- * @param {function} scopedCallback Callback to run with the new context
- * @return {ReactComponent|array<ReactComponent>}
- */
- withContext: function(newContext, scopedCallback) {
- var result;
- var previousContext = ReactContext.current;
- ReactContext.current = merge(previousContext, newContext);
- try {
- result = scopedCallback();
- } finally {
- ReactContext.current = previousContext;
- }
- return result;
- }
-
-};
-
-module.exports = ReactContext;
-
-},{"./merge":130}],35:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactCurrentOwner
- */
-
-"use strict";
-
-/**
- * Keeps track of the current owner.
- *
- * The current owner is the component who should own any components that are
- * currently being constructed.
- *
- * The depth indicate how many composite components are above this render level.
- */
-var ReactCurrentOwner = {
-
- /**
- * @internal
- * @type {ReactComponent}
- */
- current: null
-
-};
-
-module.exports = ReactCurrentOwner;
-
-},{}],36:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOM
- * @typechecks static-only
- */
-
-"use strict";
-
-var ReactDescriptor = _dereq_("./ReactDescriptor");
-var ReactDescriptorValidator = _dereq_("./ReactDescriptorValidator");
-var ReactDOMComponent = _dereq_("./ReactDOMComponent");
-
-var mergeInto = _dereq_("./mergeInto");
-var mapObject = _dereq_("./mapObject");
-
-/**
- * Creates a new React class that is idempotent and capable of containing other
- * React components. It accepts event listeners and DOM properties that are
- * valid according to `DOMProperty`.
- *
- * - Event listeners: `onClick`, `onMouseDown`, etc.
- * - DOM properties: `className`, `name`, `title`, etc.
- *
- * The `style` property functions differently from the DOM API. It accepts an
- * object mapping of style properties to values.
- *
- * @param {boolean} omitClose True if the close tag should be omitted.
- * @param {string} tag Tag name (e.g. `div`).
- * @private
- */
-function createDOMComponentClass(omitClose, tag) {
- var Constructor = function(descriptor) {
- this.construct(descriptor);
- };
- Constructor.prototype = new ReactDOMComponent(tag, omitClose);
- Constructor.prototype.constructor = Constructor;
- Constructor.displayName = tag;
-
- var ConvenienceConstructor = ReactDescriptor.createFactory(Constructor);
-
- if ("production" !== "development") {
- return ReactDescriptorValidator.createFactory(
- ConvenienceConstructor
- );
- }
-
- return ConvenienceConstructor;
-}
-
-/**
- * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.
- * This is also accessible via `React.DOM`.
- *
- * @public
- */
-var ReactDOM = mapObject({
- a: false,
- abbr: false,
- address: false,
- area: true,
- article: false,
- aside: false,
- audio: false,
- b: false,
- base: true,
- bdi: false,
- bdo: false,
- big: false,
- blockquote: false,
- body: false,
- br: true,
- button: false,
- canvas: false,
- caption: false,
- cite: false,
- code: false,
- col: true,
- colgroup: false,
- data: false,
- datalist: false,
- dd: false,
- del: false,
- details: false,
- dfn: false,
- div: false,
- dl: false,
- dt: false,
- em: false,
- embed: true,
- fieldset: false,
- figcaption: false,
- figure: false,
- footer: false,
- form: false, // NOTE: Injected, see `ReactDOMForm`.
- h1: false,
- h2: false,
- h3: false,
- h4: false,
- h5: false,
- h6: false,
- head: false,
- header: false,
- hr: true,
- html: false,
- i: false,
- iframe: false,
- img: true,
- input: true,
- ins: false,
- kbd: false,
- keygen: true,
- label: false,
- legend: false,
- li: false,
- link: true,
- main: false,
- map: false,
- mark: false,
- menu: false,
- menuitem: false, // NOTE: Close tag should be omitted, but causes problems.
- meta: true,
- meter: false,
- nav: false,
- noscript: false,
- object: false,
- ol: false,
- optgroup: false,
- option: false,
- output: false,
- p: false,
- param: true,
- pre: false,
- progress: false,
- q: false,
- rp: false,
- rt: false,
- ruby: false,
- s: false,
- samp: false,
- script: false,
- section: false,
- select: false,
- small: false,
- source: true,
- span: false,
- strong: false,
- style: false,
- sub: false,
- summary: false,
- sup: false,
- table: false,
- tbody: false,
- td: false,
- textarea: false, // NOTE: Injected, see `ReactDOMTextarea`.
- tfoot: false,
- th: false,
- thead: false,
- time: false,
- title: false,
- tr: false,
- track: true,
- u: false,
- ul: false,
- 'var': false,
- video: false,
- wbr: true,
-
- // SVG
- circle: false,
- defs: false,
- ellipse: false,
- g: false,
- line: false,
- linearGradient: false,
- mask: false,
- path: false,
- pattern: false,
- polygon: false,
- polyline: false,
- radialGradient: false,
- rect: false,
- stop: false,
- svg: false,
- text: false,
- tspan: false
-}, createDOMComponentClass);
-
-var injection = {
- injectComponentClasses: function(componentClasses) {
- mergeInto(ReactDOM, componentClasses);
- }
-};
-
-ReactDOM.injection = injection;
-
-module.exports = ReactDOM;
-
-},{"./ReactDOMComponent":38,"./ReactDescriptor":51,"./ReactDescriptorValidator":52,"./mapObject":128,"./mergeInto":132}],37:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOMButton
- */
-
-"use strict";
-
-var AutoFocusMixin = _dereq_("./AutoFocusMixin");
-var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin");
-var ReactCompositeComponent = _dereq_("./ReactCompositeComponent");
-var ReactDOM = _dereq_("./ReactDOM");
-
-var keyMirror = _dereq_("./keyMirror");
-
-// Store a reference to the <button> `ReactDOMComponent`.
-var button = ReactDOM.button;
-
-var mouseListenerNames = keyMirror({
- onClick: true,
- onDoubleClick: true,
- onMouseDown: true,
- onMouseMove: true,
- onMouseUp: true,
- onClickCapture: true,
- onDoubleClickCapture: true,
- onMouseDownCapture: true,
- onMouseMoveCapture: true,
- onMouseUpCapture: true
-});
-
-/**
- * Implements a <button> native component that does not receive mouse events
- * when `disabled` is set.
- */
-var ReactDOMButton = ReactCompositeComponent.createClass({
- displayName: 'ReactDOMButton',
-
- mixins: [AutoFocusMixin, ReactBrowserComponentMixin],
-
- render: function() {
- var props = {};
-
- // Copy the props; except the mouse listeners if we're disabled
- for (var key in this.props) {
- if (this.props.hasOwnProperty(key) &&
- (!this.props.disabled || !mouseListenerNames[key])) {
- props[key] = this.props[key];
- }
- }
-
- return button(props, this.props.children);
- }
-
-});
-
-module.exports = ReactDOMButton;
-
-},{"./AutoFocusMixin":1,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36,"./keyMirror":126}],38:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOMComponent
- * @typechecks static-only
- */
-
-"use strict";
-
-var CSSPropertyOperations = _dereq_("./CSSPropertyOperations");
-var DOMProperty = _dereq_("./DOMProperty");
-var DOMPropertyOperations = _dereq_("./DOMPropertyOperations");
-var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin");
-var ReactComponent = _dereq_("./ReactComponent");
-var ReactBrowserEventEmitter = _dereq_("./ReactBrowserEventEmitter");
-var ReactMount = _dereq_("./ReactMount");
-var ReactMultiChild = _dereq_("./ReactMultiChild");
-var ReactPerf = _dereq_("./ReactPerf");
-
-var escapeTextForBrowser = _dereq_("./escapeTextForBrowser");
-var invariant = _dereq_("./invariant");
-var keyOf = _dereq_("./keyOf");
-var merge = _dereq_("./merge");
-var mixInto = _dereq_("./mixInto");
-
-var deleteListener = ReactBrowserEventEmitter.deleteListener;
-var listenTo = ReactBrowserEventEmitter.listenTo;
-var registrationNameModules = ReactBrowserEventEmitter.registrationNameModules;
-
-// For quickly matching children type, to test if can be treated as content.
-var CONTENT_TYPES = {'string': true, 'number': true};
-
-var STYLE = keyOf({style: null});
-
-var ELEMENT_NODE_TYPE = 1;
-
-/**
- * @param {?object} props
- */
-function assertValidProps(props) {
- if (!props) {
- return;
- }
- // Note the use of `==` which checks for null or undefined.
- ("production" !== "development" ? invariant(
- props.children == null || props.dangerouslySetInnerHTML == null,
- 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
- ) : invariant(props.children == null || props.dangerouslySetInnerHTML == null));
- ("production" !== "development" ? invariant(
- props.style == null || typeof props.style === 'object',
- 'The `style` prop expects a mapping from style properties to values, ' +
- 'not a string.'
- ) : invariant(props.style == null || typeof props.style === 'object'));
-}
-
-function putListener(id, registrationName, listener, transaction) {
- var container = ReactMount.findReactContainerForID(id);
- if (container) {
- var doc = container.nodeType === ELEMENT_NODE_TYPE ?
- container.ownerDocument :
- container;
- listenTo(registrationName, doc);
- }
- transaction.getPutListenerQueue().enqueuePutListener(
- id,
- registrationName,
- listener
- );
-}
-
-
-/**
- * @constructor ReactDOMComponent
- * @extends ReactComponent
- * @extends ReactMultiChild
- */
-function ReactDOMComponent(tag, omitClose) {
- this._tagOpen = '<' + tag;
- this._tagClose = omitClose ? '' : '</' + tag + '>';
- this.tagName = tag.toUpperCase();
-}
-
-ReactDOMComponent.Mixin = {
-
- /**
- * Generates root tag markup then recurses. This method has side effects and
- * is not idempotent.
- *
- * @internal
- * @param {string} rootID The root DOM ID for this node.
- * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
- * @param {number} mountDepth number of components in the owner hierarchy
- * @return {string} The computed markup.
- */
- mountComponent: ReactPerf.measure(
- 'ReactDOMComponent',
- 'mountComponent',
- function(rootID, transaction, mountDepth) {
- ReactComponent.Mixin.mountComponent.call(
- this,
- rootID,
- transaction,
- mountDepth
- );
- assertValidProps(this.props);
- return (
- this._createOpenTagMarkupAndPutListeners(transaction) +
- this._createContentMarkup(transaction) +
- this._tagClose
- );
- }
- ),
-
- /**
- * Creates markup for the open tag and all attributes.
- *
- * This method has side effects because events get registered.
- *
- * Iterating over object properties is faster than iterating over arrays.
- * @see http://jsperf.com/obj-vs-arr-iteration
- *
- * @private
- * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
- * @return {string} Markup of opening tag.
- */
- _createOpenTagMarkupAndPutListeners: function(transaction) {
- var props = this.props;
- var ret = this._tagOpen;
-
- for (var propKey in props) {
- if (!props.hasOwnProperty(propKey)) {
- continue;
- }
- var propValue = props[propKey];
- if (propValue == null) {
- continue;
- }
- if (registrationNameModules.hasOwnProperty(propKey)) {
- putListener(this._rootNodeID, propKey, propValue, transaction);
- } else {
- if (propKey === STYLE) {
- if (propValue) {
- propValue = props.style = merge(props.style);
- }
- propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
- }
- var markup =
- DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
- if (markup) {
- ret += ' ' + markup;
- }
- }
- }
-
- // For static pages, no need to put React ID and checksum. Saves lots of
- // bytes.
- if (transaction.renderToStaticMarkup) {
- return ret + '>';
- }
-
- var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID);
- return ret + ' ' + markupForID + '>';
- },
-
- /**
- * Creates markup for the content between the tags.
- *
- * @private
- * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
- * @return {string} Content markup.
- */
- _createContentMarkup: function(transaction) {
- // Intentional use of != to avoid catching zero/false.
- var innerHTML = this.props.dangerouslySetInnerHTML;
- if (innerHTML != null) {
- if (innerHTML.__html != null) {
- return innerHTML.__html;
- }
- } else {
- var contentToUse =
- CONTENT_TYPES[typeof this.props.children] ? this.props.children : null;
- var childrenToUse = contentToUse != null ? null : this.props.children;
- if (contentToUse != null) {
- return escapeTextForBrowser(contentToUse);
- } else if (childrenToUse != null) {
- var mountImages = this.mountChildren(
- childrenToUse,
- transaction
- );
- return mountImages.join('');
- }
- }
- return '';
- },
-
- receiveComponent: function(nextDescriptor, transaction) {
- if (nextDescriptor === this._descriptor &&
- nextDescriptor._owner != null) {
- // Since descriptors are immutable after the owner is rendered,
- // we can do a cheap identity compare here to determine if this is a
- // superfluous reconcile. It's possible for state to be mutable but such
- // change should trigger an update of the owner which would recreate
- // the descriptor. We explicitly check for the existence of an owner since
- // it's possible for a descriptor created outside a composite to be
- // deeply mutated and reused.
- return;
- }
-
- ReactComponent.Mixin.receiveComponent.call(
- this,
- nextDescriptor,
- transaction
- );
- },
-
- /**
- * Updates a native DOM component after it has already been allocated and
- * attached to the DOM. Reconciles the root DOM node, then recurses.
- *
- * @param {ReactReconcileTransaction} transaction
- * @param {ReactDescriptor} prevDescriptor
- * @internal
- * @overridable
- */
- updateComponent: ReactPerf.measure(
- 'ReactDOMComponent',
- 'updateComponent',
- function(transaction, prevDescriptor) {
- assertValidProps(this._descriptor.props);
- ReactComponent.Mixin.updateComponent.call(
- this,
- transaction,
- prevDescriptor
- );
- this._updateDOMProperties(prevDescriptor.props, transaction);
- this._updateDOMChildren(prevDescriptor.props, transaction);
- }
- ),
-
- /**
- * Reconciles the properties by detecting differences in property values and
- * updating the DOM as necessary. This function is probably the single most
- * critical path for performance optimization.
- *
- * TODO: Benchmark whether checking for changed values in memory actually
- * improves performance (especially statically positioned elements).
- * TODO: Benchmark the effects of putting this at the top since 99% of props
- * do not change for a given reconciliation.
- * TODO: Benchmark areas that can be improved with caching.
- *
- * @private
- * @param {object} lastProps
- * @param {ReactReconcileTransaction} transaction
- */
- _updateDOMProperties: function(lastProps, transaction) {
- var nextProps = this.props;
- var propKey;
- var styleName;
- var styleUpdates;
- for (propKey in lastProps) {
- if (nextProps.hasOwnProperty(propKey) ||
- !lastProps.hasOwnProperty(propKey)) {
- continue;
- }
- if (propKey === STYLE) {
- var lastStyle = lastProps[propKey];
- for (styleName in lastStyle) {
- if (lastStyle.hasOwnProperty(styleName)) {
- styleUpdates = styleUpdates || {};
- styleUpdates[styleName] = '';
- }
- }
- } else if (registrationNameModules.hasOwnProperty(propKey)) {
- deleteListener(this._rootNodeID, propKey);
- } else if (
- DOMProperty.isStandardName[propKey] ||
- DOMProperty.isCustomAttribute(propKey)) {
- ReactComponent.BackendIDOperations.deletePropertyByID(
- this._rootNodeID,
- propKey
- );
- }
- }
- for (propKey in nextProps) {
- var nextProp = nextProps[propKey];
- var lastProp = lastProps[propKey];
- if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {
- continue;
- }
- if (propKey === STYLE) {
- if (nextProp) {
- nextProp = nextProps.style = merge(nextProp);
- }
- if (lastProp) {
- // Unset styles on `lastProp` but not on `nextProp`.
- for (styleName in lastProp) {
- if (lastProp.hasOwnProperty(styleName) &&
- (!nextProp || !nextProp.hasOwnProperty(styleName))) {
- styleUpdates = styleUpdates || {};
- styleUpdates[styleName] = '';
- }
- }
- // Update styles that changed since `lastProp`.
- for (styleName in nextProp) {
- if (nextProp.hasOwnProperty(styleName) &&
- lastProp[styleName] !== nextProp[styleName]) {
- styleUpdates = styleUpdates || {};
- styleUpdates[styleName] = nextProp[styleName];
- }
- }
- } else {
- // Relies on `updateStylesByID` not mutating `styleUpdates`.
- styleUpdates = nextProp;
- }
- } else if (registrationNameModules.hasOwnProperty(propKey)) {
- putListener(this._rootNodeID, propKey, nextProp, transaction);
- } else if (
- DOMProperty.isStandardName[propKey] ||
- DOMProperty.isCustomAttribute(propKey)) {
- ReactComponent.BackendIDOperations.updatePropertyByID(
- this._rootNodeID,
- propKey,
- nextProp
- );
- }
- }
- if (styleUpdates) {
- ReactComponent.BackendIDOperations.updateStylesByID(
- this._rootNodeID,
- styleUpdates
- );
- }
- },
-
- /**
- * Reconciles the children with the various properties that affect the
- * children content.
- *
- * @param {object} lastProps
- * @param {ReactReconcileTransaction} transaction
- */
- _updateDOMChildren: function(lastProps, transaction) {
- var nextProps = this.props;
-
- var lastContent =
- CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
- var nextContent =
- CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
-
- var lastHtml =
- lastProps.dangerouslySetInnerHTML &&
- lastProps.dangerouslySetInnerHTML.__html;
- var nextHtml =
- nextProps.dangerouslySetInnerHTML &&
- nextProps.dangerouslySetInnerHTML.__html;
-
- // Note the use of `!=` which checks for null or undefined.
- var lastChildren = lastContent != null ? null : lastProps.children;
- var nextChildren = nextContent != null ? null : nextProps.children;
-
- // If we're switching from children to content/html or vice versa, remove
- // the old content
- var lastHasContentOrHtml = lastContent != null || lastHtml != null;
- var nextHasContentOrHtml = nextContent != null || nextHtml != null;
- if (lastChildren != null && nextChildren == null) {
- this.updateChildren(null, transaction);
- } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
- this.updateTextContent('');
- }
-
- if (nextContent != null) {
- if (lastContent !== nextContent) {
- this.updateTextContent('' + nextContent);
- }
- } else if (nextHtml != null) {
- if (lastHtml !== nextHtml) {
- ReactComponent.BackendIDOperations.updateInnerHTMLByID(
- this._rootNodeID,
- nextHtml
- );
- }
- } else if (nextChildren != null) {
- this.updateChildren(nextChildren, transaction);
- }
- },
-
- /**
- * Destroys all event registrations for this instance. Does not remove from
- * the DOM. That must be done by the parent.
- *
- * @internal
- */
- unmountComponent: function() {
- this.unmountChildren();
- ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID);
- ReactComponent.Mixin.unmountComponent.call(this);
- }
-
-};
-
-mixInto(ReactDOMComponent, ReactComponent.Mixin);
-mixInto(ReactDOMComponent, ReactDOMComponent.Mixin);
-mixInto(ReactDOMComponent, ReactMultiChild.Mixin);
-mixInto(ReactDOMComponent, ReactBrowserComponentMixin);
-
-module.exports = ReactDOMComponent;
-
-},{"./CSSPropertyOperations":4,"./DOMProperty":10,"./DOMPropertyOperations":11,"./ReactBrowserComponentMixin":28,"./ReactBrowserEventEmitter":29,"./ReactComponent":31,"./ReactMount":61,"./ReactMultiChild":62,"./ReactPerf":65,"./escapeTextForBrowser":104,"./invariant":120,"./keyOf":127,"./merge":130,"./mixInto":133}],39:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOMForm
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-var LocalEventTrapMixin = _dereq_("./LocalEventTrapMixin");
-var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin");
-var ReactCompositeComponent = _dereq_("./ReactCompositeComponent");
-var ReactDOM = _dereq_("./ReactDOM");
-
-// Store a reference to the <form> `ReactDOMComponent`.
-var form = ReactDOM.form;
-
-/**
- * Since onSubmit doesn't bubble OR capture on the top level in IE8, we need
- * to capture it on the <form> element itself. There are lots of hacks we could
- * do to accomplish this, but the most reliable is to make <form> a
- * composite component and use `componentDidMount` to attach the event handlers.
- */
-var ReactDOMForm = ReactCompositeComponent.createClass({
- displayName: 'ReactDOMForm',
-
- mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin],
-
- render: function() {
- // TODO: Instead of using `ReactDOM` directly, we should use JSX. However,
- // `jshint` fails to parse JSX so in order for linting to work in the open
- // source repo, we need to just use `ReactDOM.form`.
- return this.transferPropsTo(form(null, this.props.children));
- },
-
- componentDidMount: function() {
- this.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset');
- this.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit');
- }
-});
-
-module.exports = ReactDOMForm;
-
-},{"./EventConstants":15,"./LocalEventTrapMixin":24,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36}],40:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOMIDOperations
- * @typechecks static-only
- */
-
-/*jslint evil: true */
-
-"use strict";
-
-var CSSPropertyOperations = _dereq_("./CSSPropertyOperations");
-var DOMChildrenOperations = _dereq_("./DOMChildrenOperations");
-var DOMPropertyOperations = _dereq_("./DOMPropertyOperations");
-var ReactMount = _dereq_("./ReactMount");
-var ReactPerf = _dereq_("./ReactPerf");
-
-var invariant = _dereq_("./invariant");
-var setInnerHTML = _dereq_("./setInnerHTML");
-
-/**
- * Errors for properties that should not be updated with `updatePropertyById()`.
- *
- * @type {object}
- * @private
- */
-var INVALID_PROPERTY_ERRORS = {
- dangerouslySetInnerHTML:
- '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',
- style: '`style` must be set using `updateStylesByID()`.'
-};
-
-/**
- * Operations used to process updates to DOM nodes. This is made injectable via
- * `ReactComponent.BackendIDOperations`.
- */
-var ReactDOMIDOperations = {
-
- /**
- * Updates a DOM node with new property values. This should only be used to
- * update DOM properties in `DOMProperty`.
- *
- * @param {string} id ID of the node to update.
- * @param {string} name A valid property name, see `DOMProperty`.
- * @param {*} value New value of the property.
- * @internal
- */
- updatePropertyByID: ReactPerf.measure(
- 'ReactDOMIDOperations',
- 'updatePropertyByID',
- function(id, name, value) {
- var node = ReactMount.getNode(id);
- ("production" !== "development" ? invariant(
- !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
- 'updatePropertyByID(...): %s',
- INVALID_PROPERTY_ERRORS[name]
- ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name)));
-
- // If we're updating to null or undefined, we should remove the property
- // from the DOM node instead of inadvertantly setting to a string. This
- // brings us in line with the same behavior we have on initial render.
- if (value != null) {
- DOMPropertyOperations.setValueForProperty(node, name, value);
- } else {
- DOMPropertyOperations.deleteValueForProperty(node, name);
- }
- }
- ),
-
- /**
- * Updates a DOM node to remove a property. This should only be used to remove
- * DOM properties in `DOMProperty`.
- *
- * @param {string} id ID of the node to update.
- * @param {string} name A property name to remove, see `DOMProperty`.
- * @internal
- */
- deletePropertyByID: ReactPerf.measure(
- 'ReactDOMIDOperations',
- 'deletePropertyByID',
- function(id, name, value) {
- var node = ReactMount.getNode(id);
- ("production" !== "development" ? invariant(
- !INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
- 'updatePropertyByID(...): %s',
- INVALID_PROPERTY_ERRORS[name]
- ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name)));
- DOMPropertyOperations.deleteValueForProperty(node, name, value);
- }
- ),
-
- /**
- * Updates a DOM node with new style values. If a value is specified as '',
- * the corresponding style property will be unset.
- *
- * @param {string} id ID of the node to update.
- * @param {object} styles Mapping from styles to values.
- * @internal
- */
- updateStylesByID: ReactPerf.measure(
- 'ReactDOMIDOperations',
- 'updateStylesByID',
- function(id, styles) {
- var node = ReactMount.getNode(id);
- CSSPropertyOperations.setValueForStyles(node, styles);
- }
- ),
-
- /**
- * Updates a DOM node's innerHTML.
- *
- * @param {string} id ID of the node to update.
- * @param {string} html An HTML string.
- * @internal
- */
- updateInnerHTMLByID: ReactPerf.measure(
- 'ReactDOMIDOperations',
- 'updateInnerHTMLByID',
- function(id, html) {
- var node = ReactMount.getNode(id);
- setInnerHTML(node, html);
- }
- ),
-
- /**
- * Updates a DOM node's text content set by `props.content`.
- *
- * @param {string} id ID of the node to update.
- * @param {string} content Text content.
- * @internal
- */
- updateTextContentByID: ReactPerf.measure(
- 'ReactDOMIDOperations',
- 'updateTextContentByID',
- function(id, content) {
- var node = ReactMount.getNode(id);
- DOMChildrenOperations.updateTextContent(node, content);
- }
- ),
-
- /**
- * Replaces a DOM node that exists in the document with markup.
- *
- * @param {string} id ID of child to be replaced.
- * @param {string} markup Dangerous markup to inject in place of child.
- * @internal
- * @see {Danger.dangerouslyReplaceNodeWithMarkup}
- */
- dangerouslyReplaceNodeWithMarkupByID: ReactPerf.measure(
- 'ReactDOMIDOperations',
- 'dangerouslyReplaceNodeWithMarkupByID',
- function(id, markup) {
- var node = ReactMount.getNode(id);
- DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
- }
- ),
-
- /**
- * Updates a component's children by processing a series of updates.
- *
- * @param {array<object>} updates List of update configurations.
- * @param {array<string>} markup List of markup strings.
- * @internal
- */
- dangerouslyProcessChildrenUpdates: ReactPerf.measure(
- 'ReactDOMIDOperations',
- 'dangerouslyProcessChildrenUpdates',
- function(updates, markup) {
- for (var i = 0; i < updates.length; i++) {
- updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
- }
- DOMChildrenOperations.processUpdates(updates, markup);
- }
- )
-};
-
-module.exports = ReactDOMIDOperations;
-
-},{"./CSSPropertyOperations":4,"./DOMChildrenOperations":9,"./DOMPropertyOperations":11,"./ReactMount":61,"./ReactPerf":65,"./invariant":120,"./setInnerHTML":138}],41:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOMImg
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-var LocalEventTrapMixin = _dereq_("./LocalEventTrapMixin");
-var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin");
-var ReactCompositeComponent = _dereq_("./ReactCompositeComponent");
-var ReactDOM = _dereq_("./ReactDOM");
-
-// Store a reference to the <img> `ReactDOMComponent`.
-var img = ReactDOM.img;
-
-/**
- * Since onLoad doesn't bubble OR capture on the top level in IE8, we need to
- * capture it on the <img> element itself. There are lots of hacks we could do
- * to accomplish this, but the most reliable is to make <img> a composite
- * component and use `componentDidMount` to attach the event handlers.
- */
-var ReactDOMImg = ReactCompositeComponent.createClass({
- displayName: 'ReactDOMImg',
- tagName: 'IMG',
-
- mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin],
-
- render: function() {
- return img(this.props);
- },
-
- componentDidMount: function() {
- this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load');
- this.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error');
- }
-});
-
-module.exports = ReactDOMImg;
-
-},{"./EventConstants":15,"./LocalEventTrapMixin":24,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36}],42:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOMInput
- */
-
-"use strict";
-
-var AutoFocusMixin = _dereq_("./AutoFocusMixin");
-var DOMPropertyOperations = _dereq_("./DOMPropertyOperations");
-var LinkedValueUtils = _dereq_("./LinkedValueUtils");
-var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin");
-var ReactCompositeComponent = _dereq_("./ReactCompositeComponent");
-var ReactDOM = _dereq_("./ReactDOM");
-var ReactMount = _dereq_("./ReactMount");
-
-var invariant = _dereq_("./invariant");
-var merge = _dereq_("./merge");
-
-// Store a reference to the <input> `ReactDOMComponent`.
-var input = ReactDOM.input;
-
-var instancesByReactID = {};
-
-/**
- * Implements an <input> native component that allows setting these optional
- * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
- *
- * If `checked` or `value` are not supplied (or null/undefined), user actions
- * that affect the checked state or value will trigger updates to the element.
- *
- * If they are supplied (and not null/undefined), the rendered element will not
- * trigger updates to the element. Instead, the props must change in order for
- * the rendered element to be updated.
- *
- * The rendered element will be initialized as unchecked (or `defaultChecked`)
- * with an empty value (or `defaultValue`).
- *
- * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
- */
-var ReactDOMInput = ReactCompositeComponent.createClass({
- displayName: 'ReactDOMInput',
-
- mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
-
- getInitialState: function() {
- var defaultValue = this.props.defaultValue;
- return {
- checked: this.props.defaultChecked || false,
- value: defaultValue != null ? defaultValue : null
- };
- },
-
- shouldComponentUpdate: function() {
- // Defer any updates to this component during the `onChange` handler.
- return !this._isChanging;
- },
-
- render: function() {
- // Clone `this.props` so we don't mutate the input.
- var props = merge(this.props);
-
- props.defaultChecked = null;
- props.defaultValue = null;
-
- var value = LinkedValueUtils.getValue(this);
- props.value = value != null ? value : this.state.value;
-
- var checked = LinkedValueUtils.getChecked(this);
- props.checked = checked != null ? checked : this.state.checked;
-
- props.onChange = this._handleChange;
-
- return input(props, this.props.children);
- },
-
- componentDidMount: function() {
- var id = ReactMount.getID(this.getDOMNode());
- instancesByReactID[id] = this;
- },
-
- componentWillUnmount: function() {
- var rootNode = this.getDOMNode();
- var id = ReactMount.getID(rootNode);
- delete instancesByReactID[id];
- },
-
- componentDidUpdate: function(prevProps, prevState, prevContext) {
- var rootNode = this.getDOMNode();
- if (this.props.checked != null) {
- DOMPropertyOperations.setValueForProperty(
- rootNode,
- 'checked',
- this.props.checked || false
- );
- }
-
- var value = LinkedValueUtils.getValue(this);
- if (value != null) {
- // Cast `value` to a string to ensure the value is set correctly. While
- // browsers typically do this as necessary, jsdom doesn't.
- DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value);
- }
- },
-
- _handleChange: function(event) {
- var returnValue;
- var onChange = LinkedValueUtils.getOnChange(this);
- if (onChange) {
- this._isChanging = true;
- returnValue = onChange.call(this, event);
- this._isChanging = false;
- }
- this.setState({
- checked: event.target.checked,
- value: event.target.value
- });
-
- var name = this.props.name;
- if (this.props.type === 'radio' && name != null) {
- var rootNode = this.getDOMNode();
- var queryRoot = rootNode;
-
- while (queryRoot.parentNode) {
- queryRoot = queryRoot.parentNode;
- }
-
- // If `rootNode.form` was non-null, then we could try `form.elements`,
- // but that sometimes behaves strangely in IE8. We could also try using
- // `form.getElementsByName`, but that will only return direct children
- // and won't include inputs that use the HTML5 `form=` attribute. Since
- // the input might not even be in a form, let's just use the global
- // `querySelectorAll` to ensure we don't miss anything.
- var group = queryRoot.querySelectorAll(
- 'input[name=' + JSON.stringify('' + name) + '][type="radio"]');
-
- for (var i = 0, groupLen = group.length; i < groupLen; i++) {
- var otherNode = group[i];
- if (otherNode === rootNode ||
- otherNode.form !== rootNode.form) {
- continue;
- }
- var otherID = ReactMount.getID(otherNode);
- ("production" !== "development" ? invariant(
- otherID,
- 'ReactDOMInput: Mixing React and non-React radio inputs with the ' +
- 'same `name` is not supported.'
- ) : invariant(otherID));
- var otherInstance = instancesByReactID[otherID];
- ("production" !== "development" ? invariant(
- otherInstance,
- 'ReactDOMInput: Unknown radio button ID %s.',
- otherID
- ) : invariant(otherInstance));
- // In some cases, this will actually change the `checked` state value.
- // In other cases, there's no change but this forces a reconcile upon
- // which componentDidUpdate will reset the DOM property to whatever it
- // should be.
- otherInstance.setState({
- checked: false
- });
- }
- }
-
- return returnValue;
- }
-
-});
-
-module.exports = ReactDOMInput;
-
-},{"./AutoFocusMixin":1,"./DOMPropertyOperations":11,"./LinkedValueUtils":23,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36,"./ReactMount":61,"./invariant":120,"./merge":130}],43:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOMOption
- */
-
-"use strict";
-
-var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin");
-var ReactCompositeComponent = _dereq_("./ReactCompositeComponent");
-var ReactDOM = _dereq_("./ReactDOM");
-
-var warning = _dereq_("./warning");
-
-// Store a reference to the <option> `ReactDOMComponent`.
-var option = ReactDOM.option;
-
-/**
- * Implements an <option> native component that warns when `selected` is set.
- */
-var ReactDOMOption = ReactCompositeComponent.createClass({
- displayName: 'ReactDOMOption',
-
- mixins: [ReactBrowserComponentMixin],
-
- componentWillMount: function() {
- // TODO (yungsters): Remove support for `selected` in <option>.
- if ("production" !== "development") {
- ("production" !== "development" ? warning(
- this.props.selected == null,
- 'Use the `defaultValue` or `value` props on <select> instead of ' +
- 'setting `selected` on <option>.'
- ) : null);
- }
- },
-
- render: function() {
- return option(this.props, this.props.children);
- }
-
-});
-
-module.exports = ReactDOMOption;
-
-},{"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36,"./warning":143}],44:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOMSelect
- */
-
-"use strict";
-
-var AutoFocusMixin = _dereq_("./AutoFocusMixin");
-var LinkedValueUtils = _dereq_("./LinkedValueUtils");
-var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin");
-var ReactCompositeComponent = _dereq_("./ReactCompositeComponent");
-var ReactDOM = _dereq_("./ReactDOM");
-
-var merge = _dereq_("./merge");
-
-// Store a reference to the <select> `ReactDOMComponent`.
-var select = ReactDOM.select;
-
-/**
- * Validation function for `value` and `defaultValue`.
- * @private
- */
-function selectValueType(props, propName, componentName) {
- if (props[propName] == null) {
- return;
- }
- if (props.multiple) {
- if (!Array.isArray(props[propName])) {
- return new Error(
- ("The `" + propName + "` prop supplied to <select> must be an array if ") +
- ("`multiple` is true.")
- );
- }
- } else {
- if (Array.isArray(props[propName])) {
- return new Error(
- ("The `" + propName + "` prop supplied to <select> must be a scalar ") +
- ("value if `multiple` is false.")
- );
- }
- }
-}
-
-/**
- * If `value` is supplied, updates <option> elements on mount and update.
- * @param {ReactComponent} component Instance of ReactDOMSelect
- * @param {?*} propValue For uncontrolled components, null/undefined. For
- * controlled components, a string (or with `multiple`, a list of strings).
- * @private
- */
-function updateOptions(component, propValue) {
- var multiple = component.props.multiple;
- var value = propValue != null ? propValue : component.state.value;
- var options = component.getDOMNode().options;
- var selectedValue, i, l;
- if (multiple) {
- selectedValue = {};
- for (i = 0, l = value.length; i < l; ++i) {
- selectedValue['' + value[i]] = true;
- }
- } else {
- selectedValue = '' + value;
- }
- for (i = 0, l = options.length; i < l; i++) {
- var selected = multiple ?
- selectedValue.hasOwnProperty(options[i].value) :
- options[i].value === selectedValue;
-
- if (selected !== options[i].selected) {
- options[i].selected = selected;
- }
- }
-}
-
-/**
- * Implements a <select> native component that allows optionally setting the
- * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
- * string. If `multiple` is true, the prop must be an array of strings.
- *
- * If `value` is not supplied (or null/undefined), user actions that change the
- * selected option will trigger updates to the rendered options.
- *
- * If it is supplied (and not null/undefined), the rendered options will not
- * update in response to user actions. Instead, the `value` prop must change in
- * order for the rendered options to update.
- *
- * If `defaultValue` is provided, any options with the supplied values will be
- * selected.
- */
-var ReactDOMSelect = ReactCompositeComponent.createClass({
- displayName: 'ReactDOMSelect',
-
- mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
-
- propTypes: {
- defaultValue: selectValueType,
- value: selectValueType
- },
-
- getInitialState: function() {
- return {value: this.props.defaultValue || (this.props.multiple ? [] : '')};
- },
-
- componentWillReceiveProps: function(nextProps) {
- if (!this.props.multiple && nextProps.multiple) {
- this.setState({value: [this.state.value]});
- } else if (this.props.multiple && !nextProps.multiple) {
- this.setState({value: this.state.value[0]});
- }
- },
-
- shouldComponentUpdate: function() {
- // Defer any updates to this component during the `onChange` handler.
- return !this._isChanging;
- },
-
- render: function() {
- // Clone `this.props` so we don't mutate the input.
- var props = merge(this.props);
-
- props.onChange = this._handleChange;
- props.value = null;
-
- return select(props, this.props.children);
- },
-
- componentDidMount: function() {
- updateOptions(this, LinkedValueUtils.getValue(this));
- },
-
- componentDidUpdate: function(prevProps) {
- var value = LinkedValueUtils.getValue(this);
- var prevMultiple = !!prevProps.multiple;
- var multiple = !!this.props.multiple;
- if (value != null || prevMultiple !== multiple) {
- updateOptions(this, value);
- }
- },
-
- _handleChange: function(event) {
- var returnValue;
- var onChange = LinkedValueUtils.getOnChange(this);
- if (onChange) {
- this._isChanging = true;
- returnValue = onChange.call(this, event);
- this._isChanging = false;
- }
-
- var selectedValue;
- if (this.props.multiple) {
- selectedValue = [];
- var options = event.target.options;
- for (var i = 0, l = options.length; i < l; i++) {
- if (options[i].selected) {
- selectedValue.push(options[i].value);
- }
- }
- } else {
- selectedValue = event.target.value;
- }
-
- this.setState({value: selectedValue});
- return returnValue;
- }
-
-});
-
-module.exports = ReactDOMSelect;
-
-},{"./AutoFocusMixin":1,"./LinkedValueUtils":23,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36,"./merge":130}],45:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOMSelection
- */
-
-"use strict";
-
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-
-var getNodeForCharacterOffset = _dereq_("./getNodeForCharacterOffset");
-var getTextContentAccessor = _dereq_("./getTextContentAccessor");
-
-/**
- * While `isCollapsed` is available on the Selection object and `collapsed`
- * is available on the Range object, IE11 sometimes gets them wrong.
- * If the anchor/focus nodes and offsets are the same, the range is collapsed.
- */
-function isCollapsed(anchorNode, anchorOffset, focusNode, focusOffset) {
- return anchorNode === focusNode && anchorOffset === focusOffset;
-}
-
-/**
- * Get the appropriate anchor and focus node/offset pairs for IE.
- *
- * The catch here is that IE's selection API doesn't provide information
- * about whether the selection is forward or backward, so we have to
- * behave as though it's always forward.
- *
- * IE text differs from modern selection in that it behaves as though
- * block elements end with a new line. This means character offsets will
- * differ between the two APIs.
- *
- * @param {DOMElement} node
- * @return {object}
- */
-function getIEOffsets(node) {
- var selection = document.selection;
- var selectedRange = selection.createRange();
- var selectedLength = selectedRange.text.length;
-
- // Duplicate selection so we can move range without breaking user selection.
- var fromStart = selectedRange.duplicate();
- fromStart.moveToElementText(node);
- fromStart.setEndPoint('EndToStart', selectedRange);
-
- var startOffset = fromStart.text.length;
- var endOffset = startOffset + selectedLength;
-
- return {
- start: startOffset,
- end: endOffset
- };
-}
-
-/**
- * @param {DOMElement} node
- * @return {?object}
- */
-function getModernOffsets(node) {
- var selection = window.getSelection();
-
- if (selection.rangeCount === 0) {
- return null;
- }
-
- var anchorNode = selection.anchorNode;
- var anchorOffset = selection.anchorOffset;
- var focusNode = selection.focusNode;
- var focusOffset = selection.focusOffset;
-
- var currentRange = selection.getRangeAt(0);
-
- // If the node and offset values are the same, the selection is collapsed.
- // `Selection.isCollapsed` is available natively, but IE sometimes gets
- // this value wrong.
- var isSelectionCollapsed = isCollapsed(
- selection.anchorNode,
- selection.anchorOffset,
- selection.focusNode,
- selection.focusOffset
- );
-
- var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length;
-
- var tempRange = currentRange.cloneRange();
- tempRange.selectNodeContents(node);
- tempRange.setEnd(currentRange.startContainer, currentRange.startOffset);
-
- var isTempRangeCollapsed = isCollapsed(
- tempRange.startContainer,
- tempRange.startOffset,
- tempRange.endContainer,
- tempRange.endOffset
- );
-
- var start = isTempRangeCollapsed ? 0 : tempRange.toString().length;
- var end = start + rangeLength;
-
- // Detect whether the selection is backward.
- var detectionRange = document.createRange();
- detectionRange.setStart(anchorNode, anchorOffset);
- detectionRange.setEnd(focusNode, focusOffset);
- var isBackward = detectionRange.collapsed;
- detectionRange.detach();
-
- return {
- start: isBackward ? end : start,
- end: isBackward ? start : end
- };
-}
-
-/**
- * @param {DOMElement|DOMTextNode} node
- * @param {object} offsets
- */
-function setIEOffsets(node, offsets) {
- var range = document.selection.createRange().duplicate();
- var start, end;
-
- if (typeof offsets.end === 'undefined') {
- start = offsets.start;
- end = start;
- } else if (offsets.start > offsets.end) {
- start = offsets.end;
- end = offsets.start;
- } else {
- start = offsets.start;
- end = offsets.end;
- }
-
- range.moveToElementText(node);
- range.moveStart('character', start);
- range.setEndPoint('EndToStart', range);
- range.moveEnd('character', end - start);
- range.select();
-}
-
-/**
- * In modern non-IE browsers, we can support both forward and backward
- * selections.
- *
- * Note: IE10+ supports the Selection object, but it does not support
- * the `extend` method, which means that even in modern IE, it's not possible
- * to programatically create a backward selection. Thus, for all IE
- * versions, we use the old IE API to create our selections.
- *
- * @param {DOMElement|DOMTextNode} node
- * @param {object} offsets
- */
-function setModernOffsets(node, offsets) {
- var selection = window.getSelection();
-
- var length = node[getTextContentAccessor()].length;
- var start = Math.min(offsets.start, length);
- var end = typeof offsets.end === 'undefined' ?
- start : Math.min(offsets.end, length);
-
- // IE 11 uses modern selection, but doesn't support the extend method.
- // Flip backward selections, so we can set with a single range.
- if (!selection.extend && start > end) {
- var temp = end;
- end = start;
- start = temp;
- }
-
- var startMarker = getNodeForCharacterOffset(node, start);
- var endMarker = getNodeForCharacterOffset(node, end);
-
- if (startMarker && endMarker) {
- var range = document.createRange();
- range.setStart(startMarker.node, startMarker.offset);
- selection.removeAllRanges();
-
- if (start > end) {
- selection.addRange(range);
- selection.extend(endMarker.node, endMarker.offset);
- } else {
- range.setEnd(endMarker.node, endMarker.offset);
- selection.addRange(range);
- }
-
- range.detach();
- }
-}
-
-var useIEOffsets = ExecutionEnvironment.canUseDOM && document.selection;
-
-var ReactDOMSelection = {
- /**
- * @param {DOMElement} node
- */
- getOffsets: useIEOffsets ? getIEOffsets : getModernOffsets,
-
- /**
- * @param {DOMElement|DOMTextNode} node
- * @param {object} offsets
- */
- setOffsets: useIEOffsets ? setIEOffsets : setModernOffsets
-};
-
-module.exports = ReactDOMSelection;
-
-},{"./ExecutionEnvironment":21,"./getNodeForCharacterOffset":113,"./getTextContentAccessor":115}],46:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDOMTextarea
- */
-
-"use strict";
-
-var AutoFocusMixin = _dereq_("./AutoFocusMixin");
-var DOMPropertyOperations = _dereq_("./DOMPropertyOperations");
-var LinkedValueUtils = _dereq_("./LinkedValueUtils");
-var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin");
-var ReactCompositeComponent = _dereq_("./ReactCompositeComponent");
-var ReactDOM = _dereq_("./ReactDOM");
-
-var invariant = _dereq_("./invariant");
-var merge = _dereq_("./merge");
-
-var warning = _dereq_("./warning");
-
-// Store a reference to the <textarea> `ReactDOMComponent`.
-var textarea = ReactDOM.textarea;
-
-/**
- * Implements a <textarea> native component that allows setting `value`, and
- * `defaultValue`. This differs from the traditional DOM API because value is
- * usually set as PCDATA children.
- *
- * If `value` is not supplied (or null/undefined), user actions that affect the
- * value will trigger updates to the element.
- *
- * If `value` is supplied (and not null/undefined), the rendered element will
- * not trigger updates to the element. Instead, the `value` prop must change in
- * order for the rendered element to be updated.
- *
- * The rendered element will be initialized with an empty value, the prop
- * `defaultValue` if specified, or the children content (deprecated).
- */
-var ReactDOMTextarea = ReactCompositeComponent.createClass({
- displayName: 'ReactDOMTextarea',
-
- mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
-
- getInitialState: function() {
- var defaultValue = this.props.defaultValue;
- // TODO (yungsters): Remove support for children content in <textarea>.
- var children = this.props.children;
- if (children != null) {
- if ("production" !== "development") {
- ("production" !== "development" ? warning(
- false,
- 'Use the `defaultValue` or `value` props instead of setting ' +
- 'children on <textarea>.'
- ) : null);
- }
- ("production" !== "development" ? invariant(
- defaultValue == null,
- 'If you supply `defaultValue` on a <textarea>, do not pass children.'
- ) : invariant(defaultValue == null));
- if (Array.isArray(children)) {
- ("production" !== "development" ? invariant(
- children.length <= 1,
- '<textarea> can only have at most one child.'
- ) : invariant(children.length <= 1));
- children = children[0];
- }
-
- defaultValue = '' + children;
- }
- if (defaultValue == null) {
- defaultValue = '';
- }
- var value = LinkedValueUtils.getValue(this);
- return {
- // We save the initial value so that `ReactDOMComponent` doesn't update
- // `textContent` (unnecessary since we update value).
- // The initial value can be a boolean or object so that's why it's
- // forced to be a string.
- initialValue: '' + (value != null ? value : defaultValue)
- };
- },
-
- shouldComponentUpdate: function() {
- // Defer any updates to this component during the `onChange` handler.
- return !this._isChanging;
- },
-
- render: function() {
- // Clone `this.props` so we don't mutate the input.
- var props = merge(this.props);
-
- ("production" !== "development" ? invariant(
- props.dangerouslySetInnerHTML == null,
- '`dangerouslySetInnerHTML` does not make sense on <textarea>.'
- ) : invariant(props.dangerouslySetInnerHTML == null));
-
- props.defaultValue = null;
- props.value = null;
- props.onChange = this._handleChange;
-
- // Always set children to the same thing. In IE9, the selection range will
- // get reset if `textContent` is mutated.
- return textarea(props, this.state.initialValue);
- },
-
- componentDidUpdate: function(prevProps, prevState, prevContext) {
- var value = LinkedValueUtils.getValue(this);
- if (value != null) {
- var rootNode = this.getDOMNode();
- // Cast `value` to a string to ensure the value is set correctly. While
- // browsers typically do this as necessary, jsdom doesn't.
- DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value);
- }
- },
-
- _handleChange: function(event) {
- var returnValue;
- var onChange = LinkedValueUtils.getOnChange(this);
- if (onChange) {
- this._isChanging = true;
- returnValue = onChange.call(this, event);
- this._isChanging = false;
- }
- this.setState({value: event.target.value});
- return returnValue;
- }
-
-});
-
-module.exports = ReactDOMTextarea;
-
-},{"./AutoFocusMixin":1,"./DOMPropertyOperations":11,"./LinkedValueUtils":23,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36,"./invariant":120,"./merge":130,"./warning":143}],47:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDefaultBatchingStrategy
- */
-
-"use strict";
-
-var ReactUpdates = _dereq_("./ReactUpdates");
-var Transaction = _dereq_("./Transaction");
-
-var emptyFunction = _dereq_("./emptyFunction");
-var mixInto = _dereq_("./mixInto");
-
-var RESET_BATCHED_UPDATES = {
- initialize: emptyFunction,
- close: function() {
- ReactDefaultBatchingStrategy.isBatchingUpdates = false;
- }
-};
-
-var FLUSH_BATCHED_UPDATES = {
- initialize: emptyFunction,
- close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates)
-};
-
-var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];
-
-function ReactDefaultBatchingStrategyTransaction() {
- this.reinitializeTransaction();
-}
-
-mixInto(ReactDefaultBatchingStrategyTransaction, Transaction.Mixin);
-mixInto(ReactDefaultBatchingStrategyTransaction, {
- getTransactionWrappers: function() {
- return TRANSACTION_WRAPPERS;
- }
-});
-
-var transaction = new ReactDefaultBatchingStrategyTransaction();
-
-var ReactDefaultBatchingStrategy = {
- isBatchingUpdates: false,
-
- /**
- * Call the provided function in a context within which calls to `setState`
- * and friends are batched such that components aren't updated unnecessarily.
- */
- batchedUpdates: function(callback, a, b) {
- var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
-
- ReactDefaultBatchingStrategy.isBatchingUpdates = true;
-
- // The code is written this way to avoid extra allocations
- if (alreadyBatchingUpdates) {
- callback(a, b);
- } else {
- transaction.perform(callback, null, a, b);
- }
- }
-};
-
-module.exports = ReactDefaultBatchingStrategy;
-
-},{"./ReactUpdates":76,"./Transaction":92,"./emptyFunction":102,"./mixInto":133}],48:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDefaultInjection
- */
-
-"use strict";
-
-var BeforeInputEventPlugin = _dereq_("./BeforeInputEventPlugin");
-var ChangeEventPlugin = _dereq_("./ChangeEventPlugin");
-var ClientReactRootIndex = _dereq_("./ClientReactRootIndex");
-var CompositionEventPlugin = _dereq_("./CompositionEventPlugin");
-var DefaultEventPluginOrder = _dereq_("./DefaultEventPluginOrder");
-var EnterLeaveEventPlugin = _dereq_("./EnterLeaveEventPlugin");
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-var HTMLDOMPropertyConfig = _dereq_("./HTMLDOMPropertyConfig");
-var MobileSafariClickEventPlugin = _dereq_("./MobileSafariClickEventPlugin");
-var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin");
-var ReactComponentBrowserEnvironment =
- _dereq_("./ReactComponentBrowserEnvironment");
-var ReactDefaultBatchingStrategy = _dereq_("./ReactDefaultBatchingStrategy");
-var ReactDOM = _dereq_("./ReactDOM");
-var ReactDOMButton = _dereq_("./ReactDOMButton");
-var ReactDOMForm = _dereq_("./ReactDOMForm");
-var ReactDOMImg = _dereq_("./ReactDOMImg");
-var ReactDOMInput = _dereq_("./ReactDOMInput");
-var ReactDOMOption = _dereq_("./ReactDOMOption");
-var ReactDOMSelect = _dereq_("./ReactDOMSelect");
-var ReactDOMTextarea = _dereq_("./ReactDOMTextarea");
-var ReactEventListener = _dereq_("./ReactEventListener");
-var ReactInjection = _dereq_("./ReactInjection");
-var ReactInstanceHandles = _dereq_("./ReactInstanceHandles");
-var ReactMount = _dereq_("./ReactMount");
-var SelectEventPlugin = _dereq_("./SelectEventPlugin");
-var ServerReactRootIndex = _dereq_("./ServerReactRootIndex");
-var SimpleEventPlugin = _dereq_("./SimpleEventPlugin");
-var SVGDOMPropertyConfig = _dereq_("./SVGDOMPropertyConfig");
-
-var createFullPageComponent = _dereq_("./createFullPageComponent");
-
-function inject() {
- ReactInjection.EventEmitter.injectReactEventListener(
- ReactEventListener
- );
-
- /**
- * Inject modules for resolving DOM hierarchy and plugin ordering.
- */
- ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder);
- ReactInjection.EventPluginHub.injectInstanceHandle(ReactInstanceHandles);
- ReactInjection.EventPluginHub.injectMount(ReactMount);
-
- /**
- * Some important event plugins included by default (without having to require
- * them).
- */
- ReactInjection.EventPluginHub.injectEventPluginsByName({
- SimpleEventPlugin: SimpleEventPlugin,
- EnterLeaveEventPlugin: EnterLeaveEventPlugin,
- ChangeEventPlugin: ChangeEventPlugin,
- CompositionEventPlugin: CompositionEventPlugin,
- MobileSafariClickEventPlugin: MobileSafariClickEventPlugin,
- SelectEventPlugin: SelectEventPlugin,
- BeforeInputEventPlugin: BeforeInputEventPlugin
- });
-
- ReactInjection.DOM.injectComponentClasses({
- button: ReactDOMButton,
- form: ReactDOMForm,
- img: ReactDOMImg,
- input: ReactDOMInput,
- option: ReactDOMOption,
- select: ReactDOMSelect,
- textarea: ReactDOMTextarea,
-
- html: createFullPageComponent(ReactDOM.html),
- head: createFullPageComponent(ReactDOM.head),
- body: createFullPageComponent(ReactDOM.body)
- });
-
- // This needs to happen after createFullPageComponent() otherwise the mixin
- // gets double injected.
- ReactInjection.CompositeComponent.injectMixin(ReactBrowserComponentMixin);
-
- ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
- ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);
-
- ReactInjection.EmptyComponent.injectEmptyComponent(ReactDOM.noscript);
-
- ReactInjection.Updates.injectReconcileTransaction(
- ReactComponentBrowserEnvironment.ReactReconcileTransaction
- );
- ReactInjection.Updates.injectBatchingStrategy(
- ReactDefaultBatchingStrategy
- );
-
- ReactInjection.RootIndex.injectCreateReactRootIndex(
- ExecutionEnvironment.canUseDOM ?
- ClientReactRootIndex.createReactRootIndex :
- ServerReactRootIndex.createReactRootIndex
- );
-
- ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment);
-
- if ("production" !== "development") {
- var url = (ExecutionEnvironment.canUseDOM && window.location.href) || '';
- if ((/[?&]react_perf\b/).test(url)) {
- var ReactDefaultPerf = _dereq_("./ReactDefaultPerf");
- ReactDefaultPerf.start();
- }
- }
-}
-
-module.exports = {
- inject: inject
-};
-
-},{"./BeforeInputEventPlugin":2,"./ChangeEventPlugin":6,"./ClientReactRootIndex":7,"./CompositionEventPlugin":8,"./DefaultEventPluginOrder":13,"./EnterLeaveEventPlugin":14,"./ExecutionEnvironment":21,"./HTMLDOMPropertyConfig":22,"./MobileSafariClickEventPlugin":25,"./ReactBrowserComponentMixin":28,"./ReactComponentBrowserEnvironment":32,"./ReactDOM":36,"./ReactDOMButton":37,"./ReactDOMForm":39,"./ReactDOMImg":41,"./ReactDOMInput":42,"./ReactDOMOption":43,"./ReactDOMSelect":44,"./ReactDOMTextarea":46,"./ReactDefaultBatchingStrategy":47,"./ReactDefaultPerf":49,"./ReactEventListener":56,"./ReactInjection":57,"./ReactInstanceHandles":59,"./ReactMount":61,"./SVGDOMPropertyConfig":77,"./SelectEventPlugin":78,"./ServerReactRootIndex":79,"./SimpleEventPlugin":80,"./createFullPageComponent":99}],49:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDefaultPerf
- * @typechecks static-only
- */
-
-"use strict";
-
-var DOMProperty = _dereq_("./DOMProperty");
-var ReactDefaultPerfAnalysis = _dereq_("./ReactDefaultPerfAnalysis");
-var ReactMount = _dereq_("./ReactMount");
-var ReactPerf = _dereq_("./ReactPerf");
-
-var performanceNow = _dereq_("./performanceNow");
-
-function roundFloat(val) {
- return Math.floor(val * 100) / 100;
-}
-
-function addValue(obj, key, val) {
- obj[key] = (obj[key] || 0) + val;
-}
-
-var ReactDefaultPerf = {
- _allMeasurements: [], // last item in the list is the current one
- _mountStack: [0],
- _injected: false,
-
- start: function() {
- if (!ReactDefaultPerf._injected) {
- ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure);
- }
-
- ReactDefaultPerf._allMeasurements.length = 0;
- ReactPerf.enableMeasure = true;
- },
-
- stop: function() {
- ReactPerf.enableMeasure = false;
- },
-
- getLastMeasurements: function() {
- return ReactDefaultPerf._allMeasurements;
- },
-
- printExclusive: function(measurements) {
- measurements = measurements || ReactDefaultPerf._allMeasurements;
- var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements);
- console.table(summary.map(function(item) {
- return {
- 'Component class name': item.componentName,
- 'Total inclusive time (ms)': roundFloat(item.inclusive),
- 'Exclusive mount time (ms)': roundFloat(item.exclusive),
- 'Exclusive render time (ms)': roundFloat(item.render),
- 'Mount time per instance (ms)': roundFloat(item.exclusive / item.count),
- 'Render time per instance (ms)': roundFloat(item.render / item.count),
- 'Instances': item.count
- };
- }));
- // TODO: ReactDefaultPerfAnalysis.getTotalTime() does not return the correct
- // number.
- },
-
- printInclusive: function(measurements) {
- measurements = measurements || ReactDefaultPerf._allMeasurements;
- var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements);
- console.table(summary.map(function(item) {
- return {
- 'Owner > component': item.componentName,
- 'Inclusive time (ms)': roundFloat(item.time),
- 'Instances': item.count
- };
- }));
- console.log(
- 'Total time:',
- ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
- );
- },
-
- printWasted: function(measurements) {
- measurements = measurements || ReactDefaultPerf._allMeasurements;
- var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(
- measurements,
- true
- );
- console.table(summary.map(function(item) {
- return {
- 'Owner > component': item.componentName,
- 'Wasted time (ms)': item.time,
- 'Instances': item.count
- };
- }));
- console.log(
- 'Total time:',
- ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
- );
- },
-
- printDOM: function(measurements) {
- measurements = measurements || ReactDefaultPerf._allMeasurements;
- var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements);
- console.table(summary.map(function(item) {
- var result = {};
- result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id;
- result['type'] = item.type;
- result['args'] = JSON.stringify(item.args);
- return result;
- }));
- console.log(
- 'Total time:',
- ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
- );
- },
-
- _recordWrite: function(id, fnName, totalTime, args) {
- // TODO: totalTime isn't that useful since it doesn't count paints/reflows
- var writes =
- ReactDefaultPerf
- ._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1]
- .writes;
- writes[id] = writes[id] || [];
- writes[id].push({
- type: fnName,
- time: totalTime,
- args: args
- });
- },
-
- measure: function(moduleName, fnName, func) {
- return function() {var args=Array.prototype.slice.call(arguments,0);
- var totalTime;
- var rv;
- var start;
-
- if (fnName === '_renderNewRootComponent' ||
- fnName === 'flushBatchedUpdates') {
- // A "measurement" is a set of metrics recorded for each flush. We want
- // to group the metrics for a given flush together so we can look at the
- // components that rendered and the DOM operations that actually
- // happened to determine the amount of "wasted work" performed.
- ReactDefaultPerf._allMeasurements.push({
- exclusive: {},
- inclusive: {},
- render: {},
- counts: {},
- writes: {},
- displayNames: {},
- totalTime: 0
- });
- start = performanceNow();
- rv = func.apply(this, args);
- ReactDefaultPerf._allMeasurements[
- ReactDefaultPerf._allMeasurements.length - 1
- ].totalTime = performanceNow() - start;
- return rv;
- } else if (moduleName === 'ReactDOMIDOperations' ||
- moduleName === 'ReactComponentBrowserEnvironment') {
- start = performanceNow();
- rv = func.apply(this, args);
- totalTime = performanceNow() - start;
-
- if (fnName === 'mountImageIntoNode') {
- var mountID = ReactMount.getID(args[1]);
- ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]);
- } else if (fnName === 'dangerouslyProcessChildrenUpdates') {
- // special format
- args[0].forEach(function(update) {
- var writeArgs = {};
- if (update.fromIndex !== null) {
- writeArgs.fromIndex = update.fromIndex;
- }
- if (update.toIndex !== null) {
- writeArgs.toIndex = update.toIndex;
- }
- if (update.textContent !== null) {
- writeArgs.textContent = update.textContent;
- }
- if (update.markupIndex !== null) {
- writeArgs.markup = args[1][update.markupIndex];
- }
- ReactDefaultPerf._recordWrite(
- update.parentID,
- update.type,
- totalTime,
- writeArgs
- );
- });
- } else {
- // basic format
- ReactDefaultPerf._recordWrite(
- args[0],
- fnName,
- totalTime,
- Array.prototype.slice.call(args, 1)
- );
- }
- return rv;
- } else if (moduleName === 'ReactCompositeComponent' && (
- fnName === 'mountComponent' ||
- fnName === 'updateComponent' || // TODO: receiveComponent()?
- fnName === '_renderValidatedComponent')) {
-
- var rootNodeID = fnName === 'mountComponent' ?
- args[0] :
- this._rootNodeID;
- var isRender = fnName === '_renderValidatedComponent';
- var isMount = fnName === 'mountComponent';
-
- var mountStack = ReactDefaultPerf._mountStack;
- var entry = ReactDefaultPerf._allMeasurements[
- ReactDefaultPerf._allMeasurements.length - 1
- ];
-
- if (isRender) {
- addValue(entry.counts, rootNodeID, 1);
- } else if (isMount) {
- mountStack.push(0);
- }
-
- start = performanceNow();
- rv = func.apply(this, args);
- totalTime = performanceNow() - start;
-
- if (isRender) {
- addValue(entry.render, rootNodeID, totalTime);
- } else if (isMount) {
- var subMountTime = mountStack.pop();
- mountStack[mountStack.length - 1] += totalTime;
- addValue(entry.exclusive, rootNodeID, totalTime - subMountTime);
- addValue(entry.inclusive, rootNodeID, totalTime);
- } else {
- addValue(entry.inclusive, rootNodeID, totalTime);
- }
-
- entry.displayNames[rootNodeID] = {
- current: this.constructor.displayName,
- owner: this._owner ? this._owner.constructor.displayName : '<root>'
- };
-
- return rv;
- } else {
- return func.apply(this, args);
- }
- };
- }
-};
-
-module.exports = ReactDefaultPerf;
-
-},{"./DOMProperty":10,"./ReactDefaultPerfAnalysis":50,"./ReactMount":61,"./ReactPerf":65,"./performanceNow":137}],50:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDefaultPerfAnalysis
- */
-
-var merge = _dereq_("./merge");
-
-// Don't try to save users less than 1.2ms (a number I made up)
-var DONT_CARE_THRESHOLD = 1.2;
-var DOM_OPERATION_TYPES = {
- 'mountImageIntoNode': 'set innerHTML',
- INSERT_MARKUP: 'set innerHTML',
- MOVE_EXISTING: 'move',
- REMOVE_NODE: 'remove',
- TEXT_CONTENT: 'set textContent',
- 'updatePropertyByID': 'update attribute',
- 'deletePropertyByID': 'delete attribute',
- 'updateStylesByID': 'update styles',
- 'updateInnerHTMLByID': 'set innerHTML',
- 'dangerouslyReplaceNodeWithMarkupByID': 'replace'
-};
-
-function getTotalTime(measurements) {
- // TODO: return number of DOM ops? could be misleading.
- // TODO: measure dropped frames after reconcile?
- // TODO: log total time of each reconcile and the top-level component
- // class that triggered it.
- var totalTime = 0;
- for (var i = 0; i < measurements.length; i++) {
- var measurement = measurements[i];
- totalTime += measurement.totalTime;
- }
- return totalTime;
-}
-
-function getDOMSummary(measurements) {
- var items = [];
- for (var i = 0; i < measurements.length; i++) {
- var measurement = measurements[i];
- var id;
-
- for (id in measurement.writes) {
- measurement.writes[id].forEach(function(write) {
- items.push({
- id: id,
- type: DOM_OPERATION_TYPES[write.type] || write.type,
- args: write.args
- });
- });
- }
- }
- return items;
-}
-
-function getExclusiveSummary(measurements) {
- var candidates = {};
- var displayName;
-
- for (var i = 0; i < measurements.length; i++) {
- var measurement = measurements[i];
- var allIDs = merge(measurement.exclusive, measurement.inclusive);
-
- for (var id in allIDs) {
- displayName = measurement.displayNames[id].current;
-
- candidates[displayName] = candidates[displayName] || {
- componentName: displayName,
- inclusive: 0,
- exclusive: 0,
- render: 0,
- count: 0
- };
- if (measurement.render[id]) {
- candidates[displayName].render += measurement.render[id];
- }
- if (measurement.exclusive[id]) {
- candidates[displayName].exclusive += measurement.exclusive[id];
- }
- if (measurement.inclusive[id]) {
- candidates[displayName].inclusive += measurement.inclusive[id];
- }
- if (measurement.counts[id]) {
- candidates[displayName].count += measurement.counts[id];
- }
- }
- }
-
- // Now make a sorted array with the results.
- var arr = [];
- for (displayName in candidates) {
- if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) {
- arr.push(candidates[displayName]);
- }
- }
-
- arr.sort(function(a, b) {
- return b.exclusive - a.exclusive;
- });
-
- return arr;
-}
-
-function getInclusiveSummary(measurements, onlyClean) {
- var candidates = {};
- var inclusiveKey;
-
- for (var i = 0; i < measurements.length; i++) {
- var measurement = measurements[i];
- var allIDs = merge(measurement.exclusive, measurement.inclusive);
- var cleanComponents;
-
- if (onlyClean) {
- cleanComponents = getUnchangedComponents(measurement);
- }
-
- for (var id in allIDs) {
- if (onlyClean && !cleanComponents[id]) {
- continue;
- }
-
- var displayName = measurement.displayNames[id];
-
- // Inclusive time is not useful for many components without knowing where
- // they are instantiated. So we aggregate inclusive time with both the
- // owner and current displayName as the key.
- inclusiveKey = displayName.owner + ' > ' + displayName.current;
-
- candidates[inclusiveKey] = candidates[inclusiveKey] || {
- componentName: inclusiveKey,
- time: 0,
- count: 0
- };
-
- if (measurement.inclusive[id]) {
- candidates[inclusiveKey].time += measurement.inclusive[id];
- }
- if (measurement.counts[id]) {
- candidates[inclusiveKey].count += measurement.counts[id];
- }
- }
- }
-
- // Now make a sorted array with the results.
- var arr = [];
- for (inclusiveKey in candidates) {
- if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) {
- arr.push(candidates[inclusiveKey]);
- }
- }
-
- arr.sort(function(a, b) {
- return b.time - a.time;
- });
-
- return arr;
-}
-
-function getUnchangedComponents(measurement) {
- // For a given reconcile, look at which components did not actually
- // render anything to the DOM and return a mapping of their ID to
- // the amount of time it took to render the entire subtree.
- var cleanComponents = {};
- var dirtyLeafIDs = Object.keys(measurement.writes);
- var allIDs = merge(measurement.exclusive, measurement.inclusive);
-
- for (var id in allIDs) {
- var isDirty = false;
- // For each component that rendered, see if a component that triggerd
- // a DOM op is in its subtree.
- for (var i = 0; i < dirtyLeafIDs.length; i++) {
- if (dirtyLeafIDs[i].indexOf(id) === 0) {
- isDirty = true;
- break;
- }
- }
- if (!isDirty && measurement.counts[id] > 0) {
- cleanComponents[id] = true;
- }
- }
- return cleanComponents;
-}
-
-var ReactDefaultPerfAnalysis = {
- getExclusiveSummary: getExclusiveSummary,
- getInclusiveSummary: getInclusiveSummary,
- getDOMSummary: getDOMSummary,
- getTotalTime: getTotalTime
-};
-
-module.exports = ReactDefaultPerfAnalysis;
-
-},{"./merge":130}],51:[function(_dereq_,module,exports){
-/**
- * Copyright 2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDescriptor
- */
-
-"use strict";
-
-var ReactContext = _dereq_("./ReactContext");
-var ReactCurrentOwner = _dereq_("./ReactCurrentOwner");
-
-var merge = _dereq_("./merge");
-var warning = _dereq_("./warning");
-
-/**
- * Warn for mutations.
- *
- * @internal
- * @param {object} object
- * @param {string} key
- */
-function defineWarningProperty(object, key) {
- Object.defineProperty(object, key, {
-
- configurable: false,
- enumerable: true,
-
- get: function() {
- if (!this._store) {
- return null;
- }
- return this._store[key];
- },
-
- set: function(value) {
- ("production" !== "development" ? warning(
- false,
- 'Don\'t set the ' + key + ' property of the component. ' +
- 'Mutate the existing props object instead.'
- ) : null);
- this._store[key] = value;
- }
-
- });
-}
-
-/**
- * This is updated to true if the membrane is successfully created.
- */
-var useMutationMembrane = false;
-
-/**
- * Warn for mutations.
- *
- * @internal
- * @param {object} descriptor
- */
-function defineMutationMembrane(prototype) {
- try {
- var pseudoFrozenProperties = {
- props: true
- };
- for (var key in pseudoFrozenProperties) {
- defineWarningProperty(prototype, key);
- }
- useMutationMembrane = true;
- } catch (x) {
- // IE will fail on defineProperty
- }
-}
-
-/**
- * Transfer static properties from the source to the target. Functions are
- * rebound to have this reflect the original source.
- */
-function proxyStaticMethods(target, source) {
- if (typeof source !== 'function') {
- return;
- }
- for (var key in source) {
- if (source.hasOwnProperty(key)) {
- var value = source[key];
- if (typeof value === 'function') {
- var bound = value.bind(source);
- // Copy any properties defined on the function, such as `isRequired` on
- // a PropTypes validator. (mergeInto refuses to work on functions.)
- for (var k in value) {
- if (value.hasOwnProperty(k)) {
- bound[k] = value[k];
- }
- }
- target[key] = bound;
- } else {
- target[key] = value;
- }
- }
- }
-}
-
-/**
- * Base constructor for all React descriptors. This is only used to make this
- * work with a dynamic instanceof check. Nothing should live on this prototype.
- *
- * @param {*} type
- * @internal
- */
-var ReactDescriptor = function() {};
-
-if ("production" !== "development") {
- defineMutationMembrane(ReactDescriptor.prototype);
-}
-
-ReactDescriptor.createFactory = function(type) {
-
- var descriptorPrototype = Object.create(ReactDescriptor.prototype);
-
- var factory = function(props, children) {
- // For consistency we currently allocate a new object for every descriptor.
- // This protects the descriptor from being mutated by the original props
- // object being mutated. It also protects the original props object from
- // being mutated by children arguments and default props. This behavior
- // comes with a performance cost and could be deprecated in the future.
- // It could also be optimized with a smarter JSX transform.
- if (props == null) {
- props = {};
- } else if (typeof props === 'object') {
- props = merge(props);
- }
-
- // Children can be more than one argument, and those are transferred onto
- // the newly allocated props object.
- var childrenLength = arguments.length - 1;
- if (childrenLength === 1) {
- props.children = children;
- } else if (childrenLength > 1) {
- var childArray = Array(childrenLength);
- for (var i = 0; i < childrenLength; i++) {
- childArray[i] = arguments[i + 1];
- }
- props.children = childArray;
- }
-
- // Initialize the descriptor object
- var descriptor = Object.create(descriptorPrototype);
-
- // Record the component responsible for creating this descriptor.
- descriptor._owner = ReactCurrentOwner.current;
-
- // TODO: Deprecate withContext, and then the context becomes accessible
- // through the owner.
- descriptor._context = ReactContext.current;
-
- if ("production" !== "development") {
- // The validation flag and props are currently mutative. We put them on
- // an external backing store so that we can freeze the whole object.
- // This can be replaced with a WeakMap once they are implemented in
- // commonly used development environments.
- descriptor._store = { validated: false, props: props };
-
- // We're not allowed to set props directly on the object so we early
- // return and rely on the prototype membrane to forward to the backing
- // store.
- if (useMutationMembrane) {
- Object.freeze(descriptor);
- return descriptor;
- }
- }
-
- descriptor.props = props;
- return descriptor;
- };
-
- // Currently we expose the prototype of the descriptor so that
- // <Foo /> instanceof Foo works. This is controversial pattern.
- factory.prototype = descriptorPrototype;
-
- // Expose the type on the factory and the prototype so that it can be
- // easily accessed on descriptors. E.g. <Foo />.type === Foo.type and for
- // static methods like <Foo />.type.staticMethod();
- // This should not be named constructor since this may not be the function
- // that created the descriptor, and it may not even be a constructor.
- factory.type = type;
- descriptorPrototype.type = type;
-
- proxyStaticMethods(factory, type);
-
- // Expose a unique constructor on the prototype is that this works with type
- // systems that compare constructor properties: <Foo />.constructor === Foo
- // This may be controversial since it requires a known factory function.
- descriptorPrototype.constructor = factory;
-
- return factory;
-
-};
-
-ReactDescriptor.cloneAndReplaceProps = function(oldDescriptor, newProps) {
- var newDescriptor = Object.create(oldDescriptor.constructor.prototype);
- // It's important that this property order matches the hidden class of the
- // original descriptor to maintain perf.
- newDescriptor._owner = oldDescriptor._owner;
- newDescriptor._context = oldDescriptor._context;
-
- if ("production" !== "development") {
- newDescriptor._store = {
- validated: oldDescriptor._store.validated,
- props: newProps
- };
- if (useMutationMembrane) {
- Object.freeze(newDescriptor);
- return newDescriptor;
- }
- }
-
- newDescriptor.props = newProps;
- return newDescriptor;
-};
-
-/**
- * Checks if a value is a valid descriptor constructor.
- *
- * @param {*}
- * @return {boolean}
- * @public
- */
-ReactDescriptor.isValidFactory = function(factory) {
- return typeof factory === 'function' &&
- factory.prototype instanceof ReactDescriptor;
-};
-
-/**
- * @param {?object} object
- * @return {boolean} True if `object` is a valid component.
- * @final
- */
-ReactDescriptor.isValidDescriptor = function(object) {
- return object instanceof ReactDescriptor;
-};
-
-module.exports = ReactDescriptor;
-
-},{"./ReactContext":34,"./ReactCurrentOwner":35,"./merge":130,"./warning":143}],52:[function(_dereq_,module,exports){
-/**
- * Copyright 2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactDescriptorValidator
- */
-
-/**
- * ReactDescriptorValidator provides a wrapper around a descriptor factory
- * which validates the props passed to the descriptor. This is intended to be
- * used only in DEV and could be replaced by a static type checker for languages
- * that support it.
- */
-
-"use strict";
-
-var ReactDescriptor = _dereq_("./ReactDescriptor");
-var ReactPropTypeLocations = _dereq_("./ReactPropTypeLocations");
-var ReactCurrentOwner = _dereq_("./ReactCurrentOwner");
-
-var monitorCodeUse = _dereq_("./monitorCodeUse");
-
-/**
- * Warn if there's no key explicitly set on dynamic arrays of children or
- * object keys are not valid. This allows us to keep track of children between
- * updates.
- */
-var ownerHasKeyUseWarning = {
- 'react_key_warning': {},
- 'react_numeric_key_warning': {}
-};
-var ownerHasMonitoredObjectMap = {};
-
-var loggedTypeFailures = {};
-
-var NUMERIC_PROPERTY_REGEX = /^\d+$/;
-
-/**
- * Gets the current owner's displayName for use in warnings.
- *
- * @internal
- * @return {?string} Display name or undefined
- */
-function getCurrentOwnerDisplayName() {
- var current = ReactCurrentOwner.current;
- return current && current.constructor.displayName || undefined;
-}
-
-/**
- * Warn if the component doesn't have an explicit key assigned to it.
- * This component is in an array. The array could grow and shrink or be
- * reordered. All children that haven't already been validated are required to
- * have a "key" property assigned to it.
- *
- * @internal
- * @param {ReactComponent} component Component that requires a key.
- * @param {*} parentType component's parent's type.
- */
-function validateExplicitKey(component, parentType) {
- if (component._store.validated || component.props.key != null) {
- return;
- }
- component._store.validated = true;
-
- warnAndMonitorForKeyUse(
- 'react_key_warning',
- 'Each child in an array should have a unique "key" prop.',
- component,
- parentType
- );
-}
-
-/**
- * Warn if the key is being defined as an object property but has an incorrect
- * value.
- *
- * @internal
- * @param {string} name Property name of the key.
- * @param {ReactComponent} component Component that requires a key.
- * @param {*} parentType component's parent's type.
- */
-function validatePropertyKey(name, component, parentType) {
- if (!NUMERIC_PROPERTY_REGEX.test(name)) {
- return;
- }
- warnAndMonitorForKeyUse(
- 'react_numeric_key_warning',
- 'Child objects should have non-numeric keys so ordering is preserved.',
- component,
- parentType
- );
-}
-
-/**
- * Shared warning and monitoring code for the key warnings.
- *
- * @internal
- * @param {string} warningID The id used when logging.
- * @param {string} message The base warning that gets output.
- * @param {ReactComponent} component Component that requires a key.
- * @param {*} parentType component's parent's type.
- */
-function warnAndMonitorForKeyUse(warningID, message, component, parentType) {
- var ownerName = getCurrentOwnerDisplayName();
- var parentName = parentType.displayName;
-
- var useName = ownerName || parentName;
- var memoizer = ownerHasKeyUseWarning[warningID];
- if (memoizer.hasOwnProperty(useName)) {
- return;
- }
- memoizer[useName] = true;
-
- message += ownerName ?
- (" Check the render method of " + ownerName + ".") :
- (" Check the renderComponent call using <" + parentName + ">.");
-
- // Usually the current owner is the offender, but if it accepts children as a
- // property, it may be the creator of the child that's responsible for
- // assigning it a key.
- var childOwnerName = null;
- if (component._owner && component._owner !== ReactCurrentOwner.current) {
- // Name of the component that originally created this child.
- childOwnerName = component._owner.constructor.displayName;
-
- message += (" It was passed a child from " + childOwnerName + ".");
- }
-
- message += ' See http://fb.me/react-warning-keys for more information.';
- monitorCodeUse(warningID, {
- component: useName,
- componentOwner: childOwnerName
- });
- console.warn(message);
-}
-
-/**
- * Log that we're using an object map. We're considering deprecating this
- * feature and replace it with proper Map and ImmutableMap data structures.
- *
- * @internal
- */
-function monitorUseOfObjectMap() {
- var currentName = getCurrentOwnerDisplayName() || '';
- if (ownerHasMonitoredObjectMap.hasOwnProperty(currentName)) {
- return;
- }
- ownerHasMonitoredObjectMap[currentName] = true;
- monitorCodeUse('react_object_map_children');
-}
-
-/**
- * Ensure that every component either is passed in a static location, in an
- * array with an explicit keys property defined, or in an object literal
- * with valid key property.
- *
- * @internal
- * @param {*} component Statically passed child of any type.
- * @param {*} parentType component's parent's type.
- * @return {boolean}
- */
-function validateChildKeys(component, parentType) {
- if (Array.isArray(component)) {
- for (var i = 0; i < component.length; i++) {
- var child = component[i];
- if (ReactDescriptor.isValidDescriptor(child)) {
- validateExplicitKey(child, parentType);
- }
- }
- } else if (ReactDescriptor.isValidDescriptor(component)) {
- // This component was passed in a valid location.
- component._store.validated = true;
- } else if (component && typeof component === 'object') {
- monitorUseOfObjectMap();
- for (var name in component) {
- validatePropertyKey(name, component[name], parentType);
- }
- }
-}
-
-/**
- * Assert that the props are valid
- *
- * @param {string} componentName Name of the component for error messages.
- * @param {object} propTypes Map of prop name to a ReactPropType
- * @param {object} props
- * @param {string} location e.g. "prop", "context", "child context"
- * @private
- */
-function checkPropTypes(componentName, propTypes, props, location) {
- for (var propName in propTypes) {
- if (propTypes.hasOwnProperty(propName)) {
- var error;
- // Prop type validation may throw. In case they do, we don't want to
- // fail the render phase where it didn't fail before. So we log it.
- // After these have been cleaned up, we'll let them throw.
- try {
- error = propTypes[propName](props, propName, componentName, location);
- } catch (ex) {
- error = ex;
- }
- if (error instanceof Error && !(error.message in loggedTypeFailures)) {
- // Only monitor this failure once because there tends to be a lot of the
- // same error.
- loggedTypeFailures[error.message] = true;
- // This will soon use the warning module
- monitorCodeUse(
- 'react_failed_descriptor_type_check',
- { message: error.message }
- );
- }
- }
- }
-}
-
-var ReactDescriptorValidator = {
-
- /**
- * Wraps a descriptor factory function in another function which validates
- * the props and context of the descriptor and warns about any failed type
- * checks.
- *
- * @param {function} factory The original descriptor factory
- * @param {object?} propTypes A prop type definition set
- * @param {object?} contextTypes A context type definition set
- * @return {object} The component descriptor, which may be invalid.
- * @private
- */
- createFactory: function(factory, propTypes, contextTypes) {
- var validatedFactory = function(props, children) {
- var descriptor = factory.apply(this, arguments);
-
- for (var i = 1; i < arguments.length; i++) {
- validateChildKeys(arguments[i], descriptor.type);
- }
-
- var name = descriptor.type.displayName;
- if (propTypes) {
- checkPropTypes(
- name,
- propTypes,
- descriptor.props,
- ReactPropTypeLocations.prop
- );
- }
- if (contextTypes) {
- checkPropTypes(
- name,
- contextTypes,
- descriptor._context,
- ReactPropTypeLocations.context
- );
- }
- return descriptor;
- };
-
- validatedFactory.prototype = factory.prototype;
- validatedFactory.type = factory.type;
-
- // Copy static properties
- for (var key in factory) {
- if (factory.hasOwnProperty(key)) {
- validatedFactory[key] = factory[key];
- }
- }
-
- return validatedFactory;
- }
-
-};
-
-module.exports = ReactDescriptorValidator;
-
-},{"./ReactCurrentOwner":35,"./ReactDescriptor":51,"./ReactPropTypeLocations":68,"./monitorCodeUse":134}],53:[function(_dereq_,module,exports){
-/**
- * Copyright 2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactEmptyComponent
- */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-
-var component;
-// This registry keeps track of the React IDs of the components that rendered to
-// `null` (in reality a placeholder such as `noscript`)
-var nullComponentIdsRegistry = {};
-
-var ReactEmptyComponentInjection = {
- injectEmptyComponent: function(emptyComponent) {
- component = emptyComponent;
- }
-};
-
-/**
- * @return {ReactComponent} component The injected empty component.
- */
-function getEmptyComponent() {
- ("production" !== "development" ? invariant(
- component,
- 'Trying to return null from a render, but no null placeholder component ' +
- 'was injected.'
- ) : invariant(component));
- return component();
-}
-
-/**
- * Mark the component as having rendered to null.
- * @param {string} id Component's `_rootNodeID`.
- */
-function registerNullComponentID(id) {
- nullComponentIdsRegistry[id] = true;
-}
-
-/**
- * Unmark the component as having rendered to null: it renders to something now.
- * @param {string} id Component's `_rootNodeID`.
- */
-function deregisterNullComponentID(id) {
- delete nullComponentIdsRegistry[id];
-}
-
-/**
- * @param {string} id Component's `_rootNodeID`.
- * @return {boolean} True if the component is rendered to null.
- */
-function isNullComponentID(id) {
- return nullComponentIdsRegistry[id];
-}
-
-var ReactEmptyComponent = {
- deregisterNullComponentID: deregisterNullComponentID,
- getEmptyComponent: getEmptyComponent,
- injection: ReactEmptyComponentInjection,
- isNullComponentID: isNullComponentID,
- registerNullComponentID: registerNullComponentID
-};
-
-module.exports = ReactEmptyComponent;
-
-},{"./invariant":120}],54:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactErrorUtils
- * @typechecks
- */
-
-"use strict";
-
-var ReactErrorUtils = {
- /**
- * Creates a guarded version of a function. This is supposed to make debugging
- * of event handlers easier. To aid debugging with the browser's debugger,
- * this currently simply returns the original function.
- *
- * @param {function} func Function to be executed
- * @param {string} name The name of the guard
- * @return {function}
- */
- guard: function(func, name) {
- return func;
- }
-};
-
-module.exports = ReactErrorUtils;
-
-},{}],55:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactEventEmitterMixin
- */
-
-"use strict";
-
-var EventPluginHub = _dereq_("./EventPluginHub");
-
-function runEventQueueInBatch(events) {
- EventPluginHub.enqueueEvents(events);
- EventPluginHub.processEventQueue();
-}
-
-var ReactEventEmitterMixin = {
-
- /**
- * Streams a fired top-level event to `EventPluginHub` where plugins have the
- * opportunity to create `ReactEvent`s to be dispatched.
- *
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {object} topLevelTarget The listening component root node.
- * @param {string} topLevelTargetID ID of `topLevelTarget`.
- * @param {object} nativeEvent Native environment event.
- */
- handleTopLevel: function(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent) {
- var events = EventPluginHub.extractEvents(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent
- );
-
- runEventQueueInBatch(events);
- }
-};
-
-module.exports = ReactEventEmitterMixin;
-
-},{"./EventPluginHub":17}],56:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactEventListener
- * @typechecks static-only
- */
-
-"use strict";
-
-var EventListener = _dereq_("./EventListener");
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-var PooledClass = _dereq_("./PooledClass");
-var ReactInstanceHandles = _dereq_("./ReactInstanceHandles");
-var ReactMount = _dereq_("./ReactMount");
-var ReactUpdates = _dereq_("./ReactUpdates");
-
-var getEventTarget = _dereq_("./getEventTarget");
-var getUnboundedScrollPosition = _dereq_("./getUnboundedScrollPosition");
-var mixInto = _dereq_("./mixInto");
-
-/**
- * Finds the parent React component of `node`.
- *
- * @param {*} node
- * @return {?DOMEventTarget} Parent container, or `null` if the specified node
- * is not nested.
- */
-function findParent(node) {
- // TODO: It may be a good idea to cache this to prevent unnecessary DOM
- // traversal, but caching is difficult to do correctly without using a
- // mutation observer to listen for all DOM changes.
- var nodeID = ReactMount.getID(node);
- var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);
- var container = ReactMount.findReactContainerForID(rootID);
- var parent = ReactMount.getFirstReactDOM(container);
- return parent;
-}
-
-// Used to store ancestor hierarchy in top level callback
-function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) {
- this.topLevelType = topLevelType;
- this.nativeEvent = nativeEvent;
- this.ancestors = [];
-}
-mixInto(TopLevelCallbackBookKeeping, {
- destructor: function() {
- this.topLevelType = null;
- this.nativeEvent = null;
- this.ancestors.length = 0;
- }
-});
-PooledClass.addPoolingTo(
- TopLevelCallbackBookKeeping,
- PooledClass.twoArgumentPooler
-);
-
-function handleTopLevelImpl(bookKeeping) {
- var topLevelTarget = ReactMount.getFirstReactDOM(
- getEventTarget(bookKeeping.nativeEvent)
- ) || window;
-
- // Loop through the hierarchy, in case there's any nested components.
- // It's important that we build the array of ancestors before calling any
- // event handlers, because event handlers can modify the DOM, leading to
- // inconsistencies with ReactMount's node cache. See #1105.
- var ancestor = topLevelTarget;
- while (ancestor) {
- bookKeeping.ancestors.push(ancestor);
- ancestor = findParent(ancestor);
- }
-
- for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) {
- topLevelTarget = bookKeeping.ancestors[i];
- var topLevelTargetID = ReactMount.getID(topLevelTarget) || '';
- ReactEventListener._handleTopLevel(
- bookKeeping.topLevelType,
- topLevelTarget,
- topLevelTargetID,
- bookKeeping.nativeEvent
- );
- }
-}
-
-function scrollValueMonitor(cb) {
- var scrollPosition = getUnboundedScrollPosition(window);
- cb(scrollPosition);
-}
-
-var ReactEventListener = {
- _enabled: true,
- _handleTopLevel: null,
-
- WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null,
-
- setHandleTopLevel: function(handleTopLevel) {
- ReactEventListener._handleTopLevel = handleTopLevel;
- },
-
- setEnabled: function(enabled) {
- ReactEventListener._enabled = !!enabled;
- },
-
- isEnabled: function() {
- return ReactEventListener._enabled;
- },
-
-
- /**
- * Traps top-level events by using event bubbling.
- *
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {string} handlerBaseName Event name (e.g. "click").
- * @param {object} handle Element on which to attach listener.
- * @return {object} An object with a remove function which will forcefully
- * remove the listener.
- * @internal
- */
- trapBubbledEvent: function(topLevelType, handlerBaseName, handle) {
- var element = handle;
- if (!element) {
- return;
- }
- return EventListener.listen(
- element,
- handlerBaseName,
- ReactEventListener.dispatchEvent.bind(null, topLevelType)
- );
- },
-
- /**
- * Traps a top-level event by using event capturing.
- *
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {string} handlerBaseName Event name (e.g. "click").
- * @param {object} handle Element on which to attach listener.
- * @return {object} An object with a remove function which will forcefully
- * remove the listener.
- * @internal
- */
- trapCapturedEvent: function(topLevelType, handlerBaseName, handle) {
- var element = handle;
- if (!element) {
- return;
- }
- return EventListener.capture(
- element,
- handlerBaseName,
- ReactEventListener.dispatchEvent.bind(null, topLevelType)
- );
- },
-
- monitorScrollValue: function(refresh) {
- var callback = scrollValueMonitor.bind(null, refresh);
- EventListener.listen(window, 'scroll', callback);
- EventListener.listen(window, 'resize', callback);
- },
-
- dispatchEvent: function(topLevelType, nativeEvent) {
- if (!ReactEventListener._enabled) {
- return;
- }
-
- var bookKeeping = TopLevelCallbackBookKeeping.getPooled(
- topLevelType,
- nativeEvent
- );
- try {
- // Event queue being processed in the same cycle allows
- // `preventDefault`.
- ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
- } finally {
- TopLevelCallbackBookKeeping.release(bookKeeping);
- }
- }
-};
-
-module.exports = ReactEventListener;
-
-},{"./EventListener":16,"./ExecutionEnvironment":21,"./PooledClass":26,"./ReactInstanceHandles":59,"./ReactMount":61,"./ReactUpdates":76,"./getEventTarget":111,"./getUnboundedScrollPosition":116,"./mixInto":133}],57:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactInjection
- */
-
-"use strict";
-
-var DOMProperty = _dereq_("./DOMProperty");
-var EventPluginHub = _dereq_("./EventPluginHub");
-var ReactComponent = _dereq_("./ReactComponent");
-var ReactCompositeComponent = _dereq_("./ReactCompositeComponent");
-var ReactDOM = _dereq_("./ReactDOM");
-var ReactEmptyComponent = _dereq_("./ReactEmptyComponent");
-var ReactBrowserEventEmitter = _dereq_("./ReactBrowserEventEmitter");
-var ReactPerf = _dereq_("./ReactPerf");
-var ReactRootIndex = _dereq_("./ReactRootIndex");
-var ReactUpdates = _dereq_("./ReactUpdates");
-
-var ReactInjection = {
- Component: ReactComponent.injection,
- CompositeComponent: ReactCompositeComponent.injection,
- DOMProperty: DOMProperty.injection,
- EmptyComponent: ReactEmptyComponent.injection,
- EventPluginHub: EventPluginHub.injection,
- DOM: ReactDOM.injection,
- EventEmitter: ReactBrowserEventEmitter.injection,
- Perf: ReactPerf.injection,
- RootIndex: ReactRootIndex.injection,
- Updates: ReactUpdates.injection
-};
-
-module.exports = ReactInjection;
-
-},{"./DOMProperty":10,"./EventPluginHub":17,"./ReactBrowserEventEmitter":29,"./ReactComponent":31,"./ReactCompositeComponent":33,"./ReactDOM":36,"./ReactEmptyComponent":53,"./ReactPerf":65,"./ReactRootIndex":72,"./ReactUpdates":76}],58:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactInputSelection
- */
-
-"use strict";
-
-var ReactDOMSelection = _dereq_("./ReactDOMSelection");
-
-var containsNode = _dereq_("./containsNode");
-var focusNode = _dereq_("./focusNode");
-var getActiveElement = _dereq_("./getActiveElement");
-
-function isInDocument(node) {
- return containsNode(document.documentElement, node);
-}
-
-/**
- * @ReactInputSelection: React input selection module. Based on Selection.js,
- * but modified to be suitable for react and has a couple of bug fixes (doesn't
- * assume buttons have range selections allowed).
- * Input selection module for React.
- */
-var ReactInputSelection = {
-
- hasSelectionCapabilities: function(elem) {
- return elem && (
- (elem.nodeName === 'INPUT' && elem.type === 'text') ||
- elem.nodeName === 'TEXTAREA' ||
- elem.contentEditable === 'true'
- );
- },
-
- getSelectionInformation: function() {
- var focusedElem = getActiveElement();
- return {
- focusedElem: focusedElem,
- selectionRange:
- ReactInputSelection.hasSelectionCapabilities(focusedElem) ?
- ReactInputSelection.getSelection(focusedElem) :
- null
- };
- },
-
- /**
- * @restoreSelection: If any selection information was potentially lost,
- * restore it. This is useful when performing operations that could remove dom
- * nodes and place them back in, resulting in focus being lost.
- */
- restoreSelection: function(priorSelectionInformation) {
- var curFocusedElem = getActiveElement();
- var priorFocusedElem = priorSelectionInformation.focusedElem;
- var priorSelectionRange = priorSelectionInformation.selectionRange;
- if (curFocusedElem !== priorFocusedElem &&
- isInDocument(priorFocusedElem)) {
- if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) {
- ReactInputSelection.setSelection(
- priorFocusedElem,
- priorSelectionRange
- );
- }
- focusNode(priorFocusedElem);
- }
- },
-
- /**
- * @getSelection: Gets the selection bounds of a focused textarea, input or
- * contentEditable node.
- * -@input: Look up selection bounds of this input
- * -@return {start: selectionStart, end: selectionEnd}
- */
- getSelection: function(input) {
- var selection;
-
- if ('selectionStart' in input) {
- // Modern browser with input or textarea.
- selection = {
- start: input.selectionStart,
- end: input.selectionEnd
- };
- } else if (document.selection && input.nodeName === 'INPUT') {
- // IE8 input.
- var range = document.selection.createRange();
- // There can only be one selection per document in IE, so it must
- // be in our element.
- if (range.parentElement() === input) {
- selection = {
- start: -range.moveStart('character', -input.value.length),
- end: -range.moveEnd('character', -input.value.length)
- };
- }
- } else {
- // Content editable or old IE textarea.
- selection = ReactDOMSelection.getOffsets(input);
- }
-
- return selection || {start: 0, end: 0};
- },
-
- /**
- * @setSelection: Sets the selection bounds of a textarea or input and focuses
- * the input.
- * -@input Set selection bounds of this input or textarea
- * -@offsets Object of same form that is returned from get*
- */
- setSelection: function(input, offsets) {
- var start = offsets.start;
- var end = offsets.end;
- if (typeof end === 'undefined') {
- end = start;
- }
-
- if ('selectionStart' in input) {
- input.selectionStart = start;
- input.selectionEnd = Math.min(end, input.value.length);
- } else if (document.selection && input.nodeName === 'INPUT') {
- var range = input.createTextRange();
- range.collapse(true);
- range.moveStart('character', start);
- range.moveEnd('character', end - start);
- range.select();
- } else {
- ReactDOMSelection.setOffsets(input, offsets);
- }
- }
-};
-
-module.exports = ReactInputSelection;
-
-},{"./ReactDOMSelection":45,"./containsNode":96,"./focusNode":106,"./getActiveElement":108}],59:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactInstanceHandles
- * @typechecks static-only
- */
-
-"use strict";
-
-var ReactRootIndex = _dereq_("./ReactRootIndex");
-
-var invariant = _dereq_("./invariant");
-
-var SEPARATOR = '.';
-var SEPARATOR_LENGTH = SEPARATOR.length;
-
-/**
- * Maximum depth of traversals before we consider the possibility of a bad ID.
- */
-var MAX_TREE_DEPTH = 100;
-
-/**
- * Creates a DOM ID prefix to use when mounting React components.
- *
- * @param {number} index A unique integer
- * @return {string} React root ID.
- * @internal
- */
-function getReactRootIDString(index) {
- return SEPARATOR + index.toString(36);
-}
-
-/**
- * Checks if a character in the supplied ID is a separator or the end.
- *
- * @param {string} id A React DOM ID.
- * @param {number} index Index of the character to check.
- * @return {boolean} True if the character is a separator or end of the ID.
- * @private
- */
-function isBoundary(id, index) {
- return id.charAt(index) === SEPARATOR || index === id.length;
-}
-
-/**
- * Checks if the supplied string is a valid React DOM ID.
- *
- * @param {string} id A React DOM ID, maybe.
- * @return {boolean} True if the string is a valid React DOM ID.
- * @private
- */
-function isValidID(id) {
- return id === '' || (
- id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR
- );
-}
-
-/**
- * Checks if the first ID is an ancestor of or equal to the second ID.
- *
- * @param {string} ancestorID
- * @param {string} descendantID
- * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`.
- * @internal
- */
-function isAncestorIDOf(ancestorID, descendantID) {
- return (
- descendantID.indexOf(ancestorID) === 0 &&
- isBoundary(descendantID, ancestorID.length)
- );
-}
-
-/**
- * Gets the parent ID of the supplied React DOM ID, `id`.
- *
- * @param {string} id ID of a component.
- * @return {string} ID of the parent, or an empty string.
- * @private
- */
-function getParentID(id) {
- return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';
-}
-
-/**
- * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the
- * supplied `destinationID`. If they are equal, the ID is returned.
- *
- * @param {string} ancestorID ID of an ancestor node of `destinationID`.
- * @param {string} destinationID ID of the destination node.
- * @return {string} Next ID on the path from `ancestorID` to `destinationID`.
- * @private
- */
-function getNextDescendantID(ancestorID, destinationID) {
- ("production" !== "development" ? invariant(
- isValidID(ancestorID) && isValidID(destinationID),
- 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.',
- ancestorID,
- destinationID
- ) : invariant(isValidID(ancestorID) && isValidID(destinationID)));
- ("production" !== "development" ? invariant(
- isAncestorIDOf(ancestorID, destinationID),
- 'getNextDescendantID(...): React has made an invalid assumption about ' +
- 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.',
- ancestorID,
- destinationID
- ) : invariant(isAncestorIDOf(ancestorID, destinationID)));
- if (ancestorID === destinationID) {
- return ancestorID;
- }
- // Skip over the ancestor and the immediate separator. Traverse until we hit
- // another separator or we reach the end of `destinationID`.
- var start = ancestorID.length + SEPARATOR_LENGTH;
- for (var i = start; i < destinationID.length; i++) {
- if (isBoundary(destinationID, i)) {
- break;
- }
- }
- return destinationID.substr(0, i);
-}
-
-/**
- * Gets the nearest common ancestor ID of two IDs.
- *
- * Using this ID scheme, the nearest common ancestor ID is the longest common
- * prefix of the two IDs that immediately preceded a "marker" in both strings.
- *
- * @param {string} oneID
- * @param {string} twoID
- * @return {string} Nearest common ancestor ID, or the empty string if none.
- * @private
- */
-function getFirstCommonAncestorID(oneID, twoID) {
- var minLength = Math.min(oneID.length, twoID.length);
- if (minLength === 0) {
- return '';
- }
- var lastCommonMarkerIndex = 0;
- // Use `<=` to traverse until the "EOL" of the shorter string.
- for (var i = 0; i <= minLength; i++) {
- if (isBoundary(oneID, i) && isBoundary(twoID, i)) {
- lastCommonMarkerIndex = i;
- } else if (oneID.charAt(i) !== twoID.charAt(i)) {
- break;
- }
- }
- var longestCommonID = oneID.substr(0, lastCommonMarkerIndex);
- ("production" !== "development" ? invariant(
- isValidID(longestCommonID),
- 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s',
- oneID,
- twoID,
- longestCommonID
- ) : invariant(isValidID(longestCommonID)));
- return longestCommonID;
-}
-
-/**
- * Traverses the parent path between two IDs (either up or down). The IDs must
- * not be the same, and there must exist a parent path between them. If the
- * callback returns `false`, traversal is stopped.
- *
- * @param {?string} start ID at which to start traversal.
- * @param {?string} stop ID at which to end traversal.
- * @param {function} cb Callback to invoke each ID with.
- * @param {?boolean} skipFirst Whether or not to skip the first node.
- * @param {?boolean} skipLast Whether or not to skip the last node.
- * @private
- */
-function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {
- start = start || '';
- stop = stop || '';
- ("production" !== "development" ? invariant(
- start !== stop,
- 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.',
- start
- ) : invariant(start !== stop));
- var traverseUp = isAncestorIDOf(stop, start);
- ("production" !== "development" ? invariant(
- traverseUp || isAncestorIDOf(start, stop),
- 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' +
- 'not have a parent path.',
- start,
- stop
- ) : invariant(traverseUp || isAncestorIDOf(start, stop)));
- // Traverse from `start` to `stop` one depth at a time.
- var depth = 0;
- var traverse = traverseUp ? getParentID : getNextDescendantID;
- for (var id = start; /* until break */; id = traverse(id, stop)) {
- var ret;
- if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) {
- ret = cb(id, traverseUp, arg);
- }
- if (ret === false || id === stop) {
- // Only break //after// visiting `stop`.
- break;
- }
- ("production" !== "development" ? invariant(
- depth++ < MAX_TREE_DEPTH,
- 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' +
- 'traversing the React DOM ID tree. This may be due to malformed IDs: %s',
- start, stop
- ) : invariant(depth++ < MAX_TREE_DEPTH));
- }
-}
-
-/**
- * Manages the IDs assigned to DOM representations of React components. This
- * uses a specific scheme in order to traverse the DOM efficiently (e.g. in
- * order to simulate events).
- *
- * @internal
- */
-var ReactInstanceHandles = {
-
- /**
- * Constructs a React root ID
- * @return {string} A React root ID.
- */
- createReactRootID: function() {
- return getReactRootIDString(ReactRootIndex.createReactRootIndex());
- },
-
- /**
- * Constructs a React ID by joining a root ID with a name.
- *
- * @param {string} rootID Root ID of a parent component.
- * @param {string} name A component's name (as flattened children).
- * @return {string} A React ID.
- * @internal
- */
- createReactID: function(rootID, name) {
- return rootID + name;
- },
-
- /**
- * Gets the DOM ID of the React component that is the root of the tree that
- * contains the React component with the supplied DOM ID.
- *
- * @param {string} id DOM ID of a React component.
- * @return {?string} DOM ID of the React component that is the root.
- * @internal
- */
- getReactRootIDFromNodeID: function(id) {
- if (id && id.charAt(0) === SEPARATOR && id.length > 1) {
- var index = id.indexOf(SEPARATOR, 1);
- return index > -1 ? id.substr(0, index) : id;
- }
- return null;
- },
-
- /**
- * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
- * should would receive a `mouseEnter` or `mouseLeave` event.
- *
- * NOTE: Does not invoke the callback on the nearest common ancestor because
- * nothing "entered" or "left" that element.
- *
- * @param {string} leaveID ID being left.
- * @param {string} enterID ID being entered.
- * @param {function} cb Callback to invoke on each entered/left ID.
- * @param {*} upArg Argument to invoke the callback with on left IDs.
- * @param {*} downArg Argument to invoke the callback with on entered IDs.
- * @internal
- */
- traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) {
- var ancestorID = getFirstCommonAncestorID(leaveID, enterID);
- if (ancestorID !== leaveID) {
- traverseParentPath(leaveID, ancestorID, cb, upArg, false, true);
- }
- if (ancestorID !== enterID) {
- traverseParentPath(ancestorID, enterID, cb, downArg, true, false);
- }
- },
-
- /**
- * Simulates the traversal of a two-phase, capture/bubble event dispatch.
- *
- * NOTE: This traversal happens on IDs without touching the DOM.
- *
- * @param {string} targetID ID of the target node.
- * @param {function} cb Callback to invoke.
- * @param {*} arg Argument to invoke the callback with.
- * @internal
- */
- traverseTwoPhase: function(targetID, cb, arg) {
- if (targetID) {
- traverseParentPath('', targetID, cb, arg, true, false);
- traverseParentPath(targetID, '', cb, arg, false, true);
- }
- },
-
- /**
- * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For
- * example, passing `.0.$row-0.1` would result in `cb` getting called
- * with `.0`, `.0.$row-0`, and `.0.$row-0.1`.
- *
- * NOTE: This traversal happens on IDs without touching the DOM.
- *
- * @param {string} targetID ID of the target node.
- * @param {function} cb Callback to invoke.
- * @param {*} arg Argument to invoke the callback with.
- * @internal
- */
- traverseAncestors: function(targetID, cb, arg) {
- traverseParentPath('', targetID, cb, arg, true, false);
- },
-
- /**
- * Exposed for unit testing.
- * @private
- */
- _getFirstCommonAncestorID: getFirstCommonAncestorID,
-
- /**
- * Exposed for unit testing.
- * @private
- */
- _getNextDescendantID: getNextDescendantID,
-
- isAncestorIDOf: isAncestorIDOf,
-
- SEPARATOR: SEPARATOR
-
-};
-
-module.exports = ReactInstanceHandles;
-
-},{"./ReactRootIndex":72,"./invariant":120}],60:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactMarkupChecksum
- */
-
-"use strict";
-
-var adler32 = _dereq_("./adler32");
-
-var ReactMarkupChecksum = {
- CHECKSUM_ATTR_NAME: 'data-react-checksum',
-
- /**
- * @param {string} markup Markup string
- * @return {string} Markup string with checksum attribute attached
- */
- addChecksumToMarkup: function(markup) {
- var checksum = adler32(markup);
- return markup.replace(
- '>',
- ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">'
- );
- },
-
- /**
- * @param {string} markup to use
- * @param {DOMElement} element root React element
- * @returns {boolean} whether or not the markup is the same
- */
- canReuseMarkup: function(markup, element) {
- var existingChecksum = element.getAttribute(
- ReactMarkupChecksum.CHECKSUM_ATTR_NAME
- );
- existingChecksum = existingChecksum && parseInt(existingChecksum, 10);
- var markupChecksum = adler32(markup);
- return markupChecksum === existingChecksum;
- }
-};
-
-module.exports = ReactMarkupChecksum;
-
-},{"./adler32":95}],61:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactMount
- */
-
-"use strict";
-
-var DOMProperty = _dereq_("./DOMProperty");
-var ReactBrowserEventEmitter = _dereq_("./ReactBrowserEventEmitter");
-var ReactCurrentOwner = _dereq_("./ReactCurrentOwner");
-var ReactDescriptor = _dereq_("./ReactDescriptor");
-var ReactInstanceHandles = _dereq_("./ReactInstanceHandles");
-var ReactPerf = _dereq_("./ReactPerf");
-
-var containsNode = _dereq_("./containsNode");
-var getReactRootElementInContainer = _dereq_("./getReactRootElementInContainer");
-var instantiateReactComponent = _dereq_("./instantiateReactComponent");
-var invariant = _dereq_("./invariant");
-var shouldUpdateReactComponent = _dereq_("./shouldUpdateReactComponent");
-var warning = _dereq_("./warning");
-
-var SEPARATOR = ReactInstanceHandles.SEPARATOR;
-
-var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
-var nodeCache = {};
-
-var ELEMENT_NODE_TYPE = 1;
-var DOC_NODE_TYPE = 9;
-
-/** Mapping from reactRootID to React component instance. */
-var instancesByReactRootID = {};
-
-/** Mapping from reactRootID to `container` nodes. */
-var containersByReactRootID = {};
-
-if ("production" !== "development") {
- /** __DEV__-only mapping from reactRootID to root elements. */
- var rootElementsByReactRootID = {};
-}
-
-// Used to store breadth-first search state in findComponentRoot.
-var findComponentRootReusableArray = [];
-
-/**
- * @param {DOMElement} container DOM element that may contain a React component.
- * @return {?string} A "reactRoot" ID, if a React component is rendered.
- */
-function getReactRootID(container) {
- var rootElement = getReactRootElementInContainer(container);
- return rootElement && ReactMount.getID(rootElement);
-}
-
-/**
- * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form
- * element can return its control whose name or ID equals ATTR_NAME. All
- * DOM nodes support `getAttributeNode` but this can also get called on
- * other objects so just return '' if we're given something other than a
- * DOM node (such as window).
- *
- * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.
- * @return {string} ID of the supplied `domNode`.
- */
-function getID(node) {
- var id = internalGetID(node);
- if (id) {
- if (nodeCache.hasOwnProperty(id)) {
- var cached = nodeCache[id];
- if (cached !== node) {
- ("production" !== "development" ? invariant(
- !isValid(cached, id),
- 'ReactMount: Two valid but unequal nodes with the same `%s`: %s',
- ATTR_NAME, id
- ) : invariant(!isValid(cached, id)));
-
- nodeCache[id] = node;
- }
- } else {
- nodeCache[id] = node;
- }
- }
-
- return id;
-}
-
-function internalGetID(node) {
- // If node is something like a window, document, or text node, none of
- // which support attributes or a .getAttribute method, gracefully return
- // the empty string, as if the attribute were missing.
- return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';
-}
-
-/**
- * Sets the React-specific ID of the given node.
- *
- * @param {DOMElement} node The DOM node whose ID will be set.
- * @param {string} id The value of the ID attribute.
- */
-function setID(node, id) {
- var oldID = internalGetID(node);
- if (oldID !== id) {
- delete nodeCache[oldID];
- }
- node.setAttribute(ATTR_NAME, id);
- nodeCache[id] = node;
-}
-
-/**
- * Finds the node with the supplied React-generated DOM ID.
- *
- * @param {string} id A React-generated DOM ID.
- * @return {DOMElement} DOM node with the suppled `id`.
- * @internal
- */
-function getNode(id) {
- if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
- nodeCache[id] = ReactMount.findReactNodeByID(id);
- }
- return nodeCache[id];
-}
-
-/**
- * A node is "valid" if it is contained by a currently mounted container.
- *
- * This means that the node does not have to be contained by a document in
- * order to be considered valid.
- *
- * @param {?DOMElement} node The candidate DOM node.
- * @param {string} id The expected ID of the node.
- * @return {boolean} Whether the node is contained by a mounted container.
- */
-function isValid(node, id) {
- if (node) {
- ("production" !== "development" ? invariant(
- internalGetID(node) === id,
- 'ReactMount: Unexpected modification of `%s`',
- ATTR_NAME
- ) : invariant(internalGetID(node) === id));
-
- var container = ReactMount.findReactContainerForID(id);
- if (container && containsNode(container, node)) {
- return true;
- }
- }
-
- return false;
-}
-
-/**
- * Causes the cache to forget about one React-specific ID.
- *
- * @param {string} id The ID to forget.
- */
-function purgeID(id) {
- delete nodeCache[id];
-}
-
-var deepestNodeSoFar = null;
-function findDeepestCachedAncestorImpl(ancestorID) {
- var ancestor = nodeCache[ancestorID];
- if (ancestor && isValid(ancestor, ancestorID)) {
- deepestNodeSoFar = ancestor;
- } else {
- // This node isn't populated in the cache, so presumably none of its
- // descendants are. Break out of the loop.
- return false;
- }
-}
-
-/**
- * Return the deepest cached node whose ID is a prefix of `targetID`.
- */
-function findDeepestCachedAncestor(targetID) {
- deepestNodeSoFar = null;
- ReactInstanceHandles.traverseAncestors(
- targetID,
- findDeepestCachedAncestorImpl
- );
-
- var foundNode = deepestNodeSoFar;
- deepestNodeSoFar = null;
- return foundNode;
-}
-
-/**
- * Mounting is the process of initializing a React component by creatings its
- * representative DOM elements and inserting them into a supplied `container`.
- * Any prior content inside `container` is destroyed in the process.
- *
- * ReactMount.renderComponent(
- * component,
- * document.getElementById('container')
- * );
- *
- * <div id="container"> <-- Supplied `container`.
- * <div data-reactid=".3"> <-- Rendered reactRoot of React
- * // ... component.
- * </div>
- * </div>
- *
- * Inside of `container`, the first element rendered is the "reactRoot".
- */
-var ReactMount = {
- /** Exposed for debugging purposes **/
- _instancesByReactRootID: instancesByReactRootID,
-
- /**
- * This is a hook provided to support rendering React components while
- * ensuring that the apparent scroll position of its `container` does not
- * change.
- *
- * @param {DOMElement} container The `container` being rendered into.
- * @param {function} renderCallback This must be called once to do the render.
- */
- scrollMonitor: function(container, renderCallback) {
- renderCallback();
- },
-
- /**
- * Take a component that's already mounted into the DOM and replace its props
- * @param {ReactComponent} prevComponent component instance already in the DOM
- * @param {ReactComponent} nextComponent component instance to render
- * @param {DOMElement} container container to render into
- * @param {?function} callback function triggered on completion
- */
- _updateRootComponent: function(
- prevComponent,
- nextComponent,
- container,
- callback) {
- var nextProps = nextComponent.props;
- ReactMount.scrollMonitor(container, function() {
- prevComponent.replaceProps(nextProps, callback);
- });
-
- if ("production" !== "development") {
- // Record the root element in case it later gets transplanted.
- rootElementsByReactRootID[getReactRootID(container)] =
- getReactRootElementInContainer(container);
- }
-
- return prevComponent;
- },
-
- /**
- * Register a component into the instance map and starts scroll value
- * monitoring
- * @param {ReactComponent} nextComponent component instance to render
- * @param {DOMElement} container container to render into
- * @return {string} reactRoot ID prefix
- */
- _registerComponent: function(nextComponent, container) {
- ("production" !== "development" ? invariant(
- container && (
- container.nodeType === ELEMENT_NODE_TYPE ||
- container.nodeType === DOC_NODE_TYPE
- ),
- '_registerComponent(...): Target container is not a DOM element.'
- ) : invariant(container && (
- container.nodeType === ELEMENT_NODE_TYPE ||
- container.nodeType === DOC_NODE_TYPE
- )));
-
- ReactBrowserEventEmitter.ensureScrollValueMonitoring();
-
- var reactRootID = ReactMount.registerContainer(container);
- instancesByReactRootID[reactRootID] = nextComponent;
- return reactRootID;
- },
-
- /**
- * Render a new component into the DOM.
- * @param {ReactComponent} nextComponent component instance to render
- * @param {DOMElement} container container to render into
- * @param {boolean} shouldReuseMarkup if we should skip the markup insertion
- * @return {ReactComponent} nextComponent
- */
- _renderNewRootComponent: ReactPerf.measure(
- 'ReactMount',
- '_renderNewRootComponent',
- function(
- nextComponent,
- container,
- shouldReuseMarkup) {
- // Various parts of our code (such as ReactCompositeComponent's
- // _renderValidatedComponent) assume that calls to render aren't nested;
- // verify that that's the case.
- ("production" !== "development" ? warning(
- ReactCurrentOwner.current == null,
- '_renderNewRootComponent(): Render methods should be a pure function ' +
- 'of props and state; triggering nested component updates from ' +
- 'render is not allowed. If necessary, trigger nested updates in ' +
- 'componentDidUpdate.'
- ) : null);
-
- var componentInstance = instantiateReactComponent(nextComponent);
- var reactRootID = ReactMount._registerComponent(
- componentInstance,
- container
- );
- componentInstance.mountComponentIntoNode(
- reactRootID,
- container,
- shouldReuseMarkup
- );
-
- if ("production" !== "development") {
- // Record the root element in case it later gets transplanted.
- rootElementsByReactRootID[reactRootID] =
- getReactRootElementInContainer(container);
- }
-
- return componentInstance;
- }
- ),
-
- /**
- * Renders a React component into the DOM in the supplied `container`.
- *
- * If the React component was previously rendered into `container`, this will
- * perform an update on it and only mutate the DOM as necessary to reflect the
- * latest React component.
- *
- * @param {ReactDescriptor} nextDescriptor Component descriptor to render.
- * @param {DOMElement} container DOM element to render into.
- * @param {?function} callback function triggered on completion
- * @return {ReactComponent} Component instance rendered in `container`.
- */
- renderComponent: function(nextDescriptor, container, callback) {
- ("production" !== "development" ? invariant(
- ReactDescriptor.isValidDescriptor(nextDescriptor),
- 'renderComponent(): Invalid component descriptor.%s',
- (
- ReactDescriptor.isValidFactory(nextDescriptor) ?
- ' Instead of passing a component class, make sure to instantiate ' +
- 'it first by calling it with props.' :
- // Check if it quacks like a descriptor
- typeof nextDescriptor.props !== "undefined" ?
- ' This may be caused by unintentionally loading two independent ' +
- 'copies of React.' :
- ''
- )
- ) : invariant(ReactDescriptor.isValidDescriptor(nextDescriptor)));
-
- var prevComponent = instancesByReactRootID[getReactRootID(container)];
-
- if (prevComponent) {
- var prevDescriptor = prevComponent._descriptor;
- if (shouldUpdateReactComponent(prevDescriptor, nextDescriptor)) {
- return ReactMount._updateRootComponent(
- prevComponent,
- nextDescriptor,
- container,
- callback
- );
- } else {
- ReactMount.unmountComponentAtNode(container);
- }
- }
-
- var reactRootElement = getReactRootElementInContainer(container);
- var containerHasReactMarkup =
- reactRootElement && ReactMount.isRenderedByReact(reactRootElement);
-
- var shouldReuseMarkup = containerHasReactMarkup && !prevComponent;
-
- var component = ReactMount._renderNewRootComponent(
- nextDescriptor,
- container,
- shouldReuseMarkup
- );
- callback && callback.call(component);
- return component;
- },
-
- /**
- * Constructs a component instance of `constructor` with `initialProps` and
- * renders it into the supplied `container`.
- *
- * @param {function} constructor React component constructor.
- * @param {?object} props Initial props of the component instance.
- * @param {DOMElement} container DOM element to render into.
- * @return {ReactComponent} Component instance rendered in `container`.
- */
- constructAndRenderComponent: function(constructor, props, container) {
- return ReactMount.renderComponent(constructor(props), container);
- },
-
- /**
- * Constructs a component instance of `constructor` with `initialProps` and
- * renders it into a container node identified by supplied `id`.
- *
- * @param {function} componentConstructor React component constructor
- * @param {?object} props Initial props of the component instance.
- * @param {string} id ID of the DOM element to render into.
- * @return {ReactComponent} Component instance rendered in the container node.
- */
- constructAndRenderComponentByID: function(constructor, props, id) {
- var domNode = document.getElementById(id);
- ("production" !== "development" ? invariant(
- domNode,
- 'Tried to get element with id of "%s" but it is not present on the page.',
- id
- ) : invariant(domNode));
- return ReactMount.constructAndRenderComponent(constructor, props, domNode);
- },
-
- /**
- * Registers a container node into which React components will be rendered.
- * This also creates the "reactRoot" ID that will be assigned to the element
- * rendered within.
- *
- * @param {DOMElement} container DOM element to register as a container.
- * @return {string} The "reactRoot" ID of elements rendered within.
- */
- registerContainer: function(container) {
- var reactRootID = getReactRootID(container);
- if (reactRootID) {
- // If one exists, make sure it is a valid "reactRoot" ID.
- reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID);
- }
- if (!reactRootID) {
- // No valid "reactRoot" ID found, create one.
- reactRootID = ReactInstanceHandles.createReactRootID();
- }
- containersByReactRootID[reactRootID] = container;
- return reactRootID;
- },
-
- /**
- * Unmounts and destroys the React component rendered in the `container`.
- *
- * @param {DOMElement} container DOM element containing a React component.
- * @return {boolean} True if a component was found in and unmounted from
- * `container`
- */
- unmountComponentAtNode: function(container) {
- // Various parts of our code (such as ReactCompositeComponent's
- // _renderValidatedComponent) assume that calls to render aren't nested;
- // verify that that's the case. (Strictly speaking, unmounting won't cause a
- // render but we still don't expect to be in a render call here.)
- ("production" !== "development" ? warning(
- ReactCurrentOwner.current == null,
- 'unmountComponentAtNode(): Render methods should be a pure function of ' +
- 'props and state; triggering nested component updates from render is ' +
- 'not allowed. If necessary, trigger nested updates in ' +
- 'componentDidUpdate.'
- ) : null);
-
- var reactRootID = getReactRootID(container);
- var component = instancesByReactRootID[reactRootID];
- if (!component) {
- return false;
- }
- ReactMount.unmountComponentFromNode(component, container);
- delete instancesByReactRootID[reactRootID];
- delete containersByReactRootID[reactRootID];
- if ("production" !== "development") {
- delete rootElementsByReactRootID[reactRootID];
- }
- return true;
- },
-
- /**
- * Unmounts a component and removes it from the DOM.
- *
- * @param {ReactComponent} instance React component instance.
- * @param {DOMElement} container DOM element to unmount from.
- * @final
- * @internal
- * @see {ReactMount.unmountComponentAtNode}
- */
- unmountComponentFromNode: function(instance, container) {
- instance.unmountComponent();
-
- if (container.nodeType === DOC_NODE_TYPE) {
- container = container.documentElement;
- }
-
- // http://jsperf.com/emptying-a-node
- while (container.lastChild) {
- container.removeChild(container.lastChild);
- }
- },
-
- /**
- * Finds the container DOM element that contains React component to which the
- * supplied DOM `id` belongs.
- *
- * @param {string} id The ID of an element rendered by a React component.
- * @return {?DOMElement} DOM element that contains the `id`.
- */
- findReactContainerForID: function(id) {
- var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id);
- var container = containersByReactRootID[reactRootID];
-
- if ("production" !== "development") {
- var rootElement = rootElementsByReactRootID[reactRootID];
- if (rootElement && rootElement.parentNode !== container) {
- ("production" !== "development" ? invariant(
- // Call internalGetID here because getID calls isValid which calls
- // findReactContainerForID (this function).
- internalGetID(rootElement) === reactRootID,
- 'ReactMount: Root element ID differed from reactRootID.'
- ) : invariant(// Call internalGetID here because getID calls isValid which calls
- // findReactContainerForID (this function).
- internalGetID(rootElement) === reactRootID));
-
- var containerChild = container.firstChild;
- if (containerChild &&
- reactRootID === internalGetID(containerChild)) {
- // If the container has a new child with the same ID as the old
- // root element, then rootElementsByReactRootID[reactRootID] is
- // just stale and needs to be updated. The case that deserves a
- // warning is when the container is empty.
- rootElementsByReactRootID[reactRootID] = containerChild;
- } else {
- console.warn(
- 'ReactMount: Root element has been removed from its original ' +
- 'container. New container:', rootElement.parentNode
- );
- }
- }
- }
-
- return container;
- },
-
- /**
- * Finds an element rendered by React with the supplied ID.
- *
- * @param {string} id ID of a DOM node in the React component.
- * @return {DOMElement} Root DOM node of the React component.
- */
- findReactNodeByID: function(id) {
- var reactRoot = ReactMount.findReactContainerForID(id);
- return ReactMount.findComponentRoot(reactRoot, id);
- },
-
- /**
- * True if the supplied `node` is rendered by React.
- *
- * @param {*} node DOM Element to check.
- * @return {boolean} True if the DOM Element appears to be rendered by React.
- * @internal
- */
- isRenderedByReact: function(node) {
- if (node.nodeType !== 1) {
- // Not a DOMElement, therefore not a React component
- return false;
- }
- var id = ReactMount.getID(node);
- return id ? id.charAt(0) === SEPARATOR : false;
- },
-
- /**
- * Traverses up the ancestors of the supplied node to find a node that is a
- * DOM representation of a React component.
- *
- * @param {*} node
- * @return {?DOMEventTarget}
- * @internal
- */
- getFirstReactDOM: function(node) {
- var current = node;
- while (current && current.parentNode !== current) {
- if (ReactMount.isRenderedByReact(current)) {
- return current;
- }
- current = current.parentNode;
- }
- return null;
- },
-
- /**
- * Finds a node with the supplied `targetID` inside of the supplied
- * `ancestorNode`. Exploits the ID naming scheme to perform the search
- * quickly.
- *
- * @param {DOMEventTarget} ancestorNode Search from this root.
- * @pararm {string} targetID ID of the DOM representation of the component.
- * @return {DOMEventTarget} DOM node with the supplied `targetID`.
- * @internal
- */
- findComponentRoot: function(ancestorNode, targetID) {
- var firstChildren = findComponentRootReusableArray;
- var childIndex = 0;
-
- var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode;
-
- firstChildren[0] = deepestAncestor.firstChild;
- firstChildren.length = 1;
-
- while (childIndex < firstChildren.length) {
- var child = firstChildren[childIndex++];
- var targetChild;
-
- while (child) {
- var childID = ReactMount.getID(child);
- if (childID) {
- // Even if we find the node we're looking for, we finish looping
- // through its siblings to ensure they're cached so that we don't have
- // to revisit this node again. Otherwise, we make n^2 calls to getID
- // when visiting the many children of a single node in order.
-
- if (targetID === childID) {
- targetChild = child;
- } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) {
- // If we find a child whose ID is an ancestor of the given ID,
- // then we can be sure that we only want to search the subtree
- // rooted at this child, so we can throw out the rest of the
- // search state.
- firstChildren.length = childIndex = 0;
- firstChildren.push(child.firstChild);
- }
-
- } else {
- // If this child had no ID, then there's a chance that it was
- // injected automatically by the browser, as when a `<table>`
- // element sprouts an extra `<tbody>` child as a side effect of
- // `.innerHTML` parsing. Optimistically continue down this
- // branch, but not before examining the other siblings.
- firstChildren.push(child.firstChild);
- }
-
- child = child.nextSibling;
- }
-
- if (targetChild) {
- // Emptying firstChildren/findComponentRootReusableArray is
- // not necessary for correctness, but it helps the GC reclaim
- // any nodes that were left at the end of the search.
- firstChildren.length = 0;
-
- return targetChild;
- }
- }
-
- firstChildren.length = 0;
-
- ("production" !== "development" ? invariant(
- false,
- 'findComponentRoot(..., %s): Unable to find element. This probably ' +
- 'means the DOM was unexpectedly mutated (e.g., by the browser), ' +
- 'usually due to forgetting a <tbody> when using tables, nesting <p> ' +
- 'or <a> tags, or using non-SVG elements in an <svg> parent. Try ' +
- 'inspecting the child nodes of the element with React ID `%s`.',
- targetID,
- ReactMount.getID(ancestorNode)
- ) : invariant(false));
- },
-
-
- /**
- * React ID utilities.
- */
-
- getReactRootID: getReactRootID,
-
- getID: getID,
-
- setID: setID,
-
- getNode: getNode,
-
- purgeID: purgeID
-};
-
-module.exports = ReactMount;
-
-},{"./DOMProperty":10,"./ReactBrowserEventEmitter":29,"./ReactCurrentOwner":35,"./ReactDescriptor":51,"./ReactInstanceHandles":59,"./ReactPerf":65,"./containsNode":96,"./getReactRootElementInContainer":114,"./instantiateReactComponent":119,"./invariant":120,"./shouldUpdateReactComponent":140,"./warning":143}],62:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactMultiChild
- * @typechecks static-only
- */
-
-"use strict";
-
-var ReactComponent = _dereq_("./ReactComponent");
-var ReactMultiChildUpdateTypes = _dereq_("./ReactMultiChildUpdateTypes");
-
-var flattenChildren = _dereq_("./flattenChildren");
-var instantiateReactComponent = _dereq_("./instantiateReactComponent");
-var shouldUpdateReactComponent = _dereq_("./shouldUpdateReactComponent");
-
-/**
- * Updating children of a component may trigger recursive updates. The depth is
- * used to batch recursive updates to render markup more efficiently.
- *
- * @type {number}
- * @private
- */
-var updateDepth = 0;
-
-/**
- * Queue of update configuration objects.
- *
- * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`.
- *
- * @type {array<object>}
- * @private
- */
-var updateQueue = [];
-
-/**
- * Queue of markup to be rendered.
- *
- * @type {array<string>}
- * @private
- */
-var markupQueue = [];
-
-/**
- * Enqueues markup to be rendered and inserted at a supplied index.
- *
- * @param {string} parentID ID of the parent component.
- * @param {string} markup Markup that renders into an element.
- * @param {number} toIndex Destination index.
- * @private
- */
-function enqueueMarkup(parentID, markup, toIndex) {
- // NOTE: Null values reduce hidden classes.
- updateQueue.push({
- parentID: parentID,
- parentNode: null,
- type: ReactMultiChildUpdateTypes.INSERT_MARKUP,
- markupIndex: markupQueue.push(markup) - 1,
- textContent: null,
- fromIndex: null,
- toIndex: toIndex
- });
-}
-
-/**
- * Enqueues moving an existing element to another index.
- *
- * @param {string} parentID ID of the parent component.
- * @param {number} fromIndex Source index of the existing element.
- * @param {number} toIndex Destination index of the element.
- * @private
- */
-function enqueueMove(parentID, fromIndex, toIndex) {
- // NOTE: Null values reduce hidden classes.
- updateQueue.push({
- parentID: parentID,
- parentNode: null,
- type: ReactMultiChildUpdateTypes.MOVE_EXISTING,
- markupIndex: null,
- textContent: null,
- fromIndex: fromIndex,
- toIndex: toIndex
- });
-}
-
-/**
- * Enqueues removing an element at an index.
- *
- * @param {string} parentID ID of the parent component.
- * @param {number} fromIndex Index of the element to remove.
- * @private
- */
-function enqueueRemove(parentID, fromIndex) {
- // NOTE: Null values reduce hidden classes.
- updateQueue.push({
- parentID: parentID,
- parentNode: null,
- type: ReactMultiChildUpdateTypes.REMOVE_NODE,
- markupIndex: null,
- textContent: null,
- fromIndex: fromIndex,
- toIndex: null
- });
-}
-
-/**
- * Enqueues setting the text content.
- *
- * @param {string} parentID ID of the parent component.
- * @param {string} textContent Text content to set.
- * @private
- */
-function enqueueTextContent(parentID, textContent) {
- // NOTE: Null values reduce hidden classes.
- updateQueue.push({
- parentID: parentID,
- parentNode: null,
- type: ReactMultiChildUpdateTypes.TEXT_CONTENT,
- markupIndex: null,
- textContent: textContent,
- fromIndex: null,
- toIndex: null
- });
-}
-
-/**
- * Processes any enqueued updates.
- *
- * @private
- */
-function processQueue() {
- if (updateQueue.length) {
- ReactComponent.BackendIDOperations.dangerouslyProcessChildrenUpdates(
- updateQueue,
- markupQueue
- );
- clearQueue();
- }
-}
-
-/**
- * Clears any enqueued updates.
- *
- * @private
- */
-function clearQueue() {
- updateQueue.length = 0;
- markupQueue.length = 0;
-}
-
-/**
- * ReactMultiChild are capable of reconciling multiple children.
- *
- * @class ReactMultiChild
- * @internal
- */
-var ReactMultiChild = {
-
- /**
- * Provides common functionality for components that must reconcile multiple
- * children. This is used by `ReactDOMComponent` to mount, update, and
- * unmount child components.
- *
- * @lends {ReactMultiChild.prototype}
- */
- Mixin: {
-
- /**
- * Generates a "mount image" for each of the supplied children. In the case
- * of `ReactDOMComponent`, a mount image is a string of markup.
- *
- * @param {?object} nestedChildren Nested child maps.
- * @return {array} An array of mounted representations.
- * @internal
- */
- mountChildren: function(nestedChildren, transaction) {
- var children = flattenChildren(nestedChildren);
- var mountImages = [];
- var index = 0;
- this._renderedChildren = children;
- for (var name in children) {
- var child = children[name];
- if (children.hasOwnProperty(name)) {
- // The rendered children must be turned into instances as they're
- // mounted.
- var childInstance = instantiateReactComponent(child);
- children[name] = childInstance;
- // Inlined for performance, see `ReactInstanceHandles.createReactID`.
- var rootID = this._rootNodeID + name;
- var mountImage = childInstance.mountComponent(
- rootID,
- transaction,
- this._mountDepth + 1
- );
- childInstance._mountIndex = index;
- mountImages.push(mountImage);
- index++;
- }
- }
- return mountImages;
- },
-
- /**
- * Replaces any rendered children with a text content string.
- *
- * @param {string} nextContent String of content.
- * @internal
- */
- updateTextContent: function(nextContent) {
- updateDepth++;
- var errorThrown = true;
- try {
- var prevChildren = this._renderedChildren;
- // Remove any rendered children.
- for (var name in prevChildren) {
- if (prevChildren.hasOwnProperty(name)) {
- this._unmountChildByName(prevChildren[name], name);
- }
- }
- // Set new text content.
- this.setTextContent(nextContent);
- errorThrown = false;
- } finally {
- updateDepth--;
- if (!updateDepth) {
- errorThrown ? clearQueue() : processQueue();
- }
- }
- },
-
- /**
- * Updates the rendered children with new children.
- *
- * @param {?object} nextNestedChildren Nested child maps.
- * @param {ReactReconcileTransaction} transaction
- * @internal
- */
- updateChildren: function(nextNestedChildren, transaction) {
- updateDepth++;
- var errorThrown = true;
- try {
- this._updateChildren(nextNestedChildren, transaction);
- errorThrown = false;
- } finally {
- updateDepth--;
- if (!updateDepth) {
- errorThrown ? clearQueue() : processQueue();
- }
- }
- },
-
- /**
- * Improve performance by isolating this hot code path from the try/catch
- * block in `updateChildren`.
- *
- * @param {?object} nextNestedChildren Nested child maps.
- * @param {ReactReconcileTransaction} transaction
- * @final
- * @protected
- */
- _updateChildren: function(nextNestedChildren, transaction) {
- var nextChildren = flattenChildren(nextNestedChildren);
- var prevChildren = this._renderedChildren;
- if (!nextChildren && !prevChildren) {
- return;
- }
- var name;
- // `nextIndex` will increment for each child in `nextChildren`, but
- // `lastIndex` will be the last index visited in `prevChildren`.
- var lastIndex = 0;
- var nextIndex = 0;
- for (name in nextChildren) {
- if (!nextChildren.hasOwnProperty(name)) {
- continue;
- }
- var prevChild = prevChildren && prevChildren[name];
- var prevDescriptor = prevChild && prevChild._descriptor;
- var nextDescriptor = nextChildren[name];
- if (shouldUpdateReactComponent(prevDescriptor, nextDescriptor)) {
- this.moveChild(prevChild, nextIndex, lastIndex);
- lastIndex = Math.max(prevChild._mountIndex, lastIndex);
- prevChild.receiveComponent(nextDescriptor, transaction);
- prevChild._mountIndex = nextIndex;
- } else {
- if (prevChild) {
- // Update `lastIndex` before `_mountIndex` gets unset by unmounting.
- lastIndex = Math.max(prevChild._mountIndex, lastIndex);
- this._unmountChildByName(prevChild, name);
- }
- // The child must be instantiated before it's mounted.
- var nextChildInstance = instantiateReactComponent(nextDescriptor);
- this._mountChildByNameAtIndex(
- nextChildInstance, name, nextIndex, transaction
- );
- }
- nextIndex++;
- }
- // Remove children that are no longer present.
- for (name in prevChildren) {
- if (prevChildren.hasOwnProperty(name) &&
- !(nextChildren && nextChildren[name])) {
- this._unmountChildByName(prevChildren[name], name);
- }
- }
- },
-
- /**
- * Unmounts all rendered children. This should be used to clean up children
- * when this component is unmounted.
- *
- * @internal
- */
- unmountChildren: function() {
- var renderedChildren = this._renderedChildren;
- for (var name in renderedChildren) {
- var renderedChild = renderedChildren[name];
- // TODO: When is this not true?
- if (renderedChild.unmountComponent) {
- renderedChild.unmountComponent();
- }
- }
- this._renderedChildren = null;
- },
-
- /**
- * Moves a child component to the supplied index.
- *
- * @param {ReactComponent} child Component to move.
- * @param {number} toIndex Destination index of the element.
- * @param {number} lastIndex Last index visited of the siblings of `child`.
- * @protected
- */
- moveChild: function(child, toIndex, lastIndex) {
- // If the index of `child` is less than `lastIndex`, then it needs to
- // be moved. Otherwise, we do not need to move it because a child will be
- // inserted or moved before `child`.
- if (child._mountIndex < lastIndex) {
- enqueueMove(this._rootNodeID, child._mountIndex, toIndex);
- }
- },
-
- /**
- * Creates a child component.
- *
- * @param {ReactComponent} child Component to create.
- * @param {string} mountImage Markup to insert.
- * @protected
- */
- createChild: function(child, mountImage) {
- enqueueMarkup(this._rootNodeID, mountImage, child._mountIndex);
- },
-
- /**
- * Removes a child component.
- *
- * @param {ReactComponent} child Child to remove.
- * @protected
- */
- removeChild: function(child) {
- enqueueRemove(this._rootNodeID, child._mountIndex);
- },
-
- /**
- * Sets this text content string.
- *
- * @param {string} textContent Text content to set.
- * @protected
- */
- setTextContent: function(textContent) {
- enqueueTextContent(this._rootNodeID, textContent);
- },
-
- /**
- * Mounts a child with the supplied name.
- *
- * NOTE: This is part of `updateChildren` and is here for readability.
- *
- * @param {ReactComponent} child Component to mount.
- * @param {string} name Name of the child.
- * @param {number} index Index at which to insert the child.
- * @param {ReactReconcileTransaction} transaction
- * @private
- */
- _mountChildByNameAtIndex: function(child, name, index, transaction) {
- // Inlined for performance, see `ReactInstanceHandles.createReactID`.
- var rootID = this._rootNodeID + name;
- var mountImage = child.mountComponent(
- rootID,
- transaction,
- this._mountDepth + 1
- );
- child._mountIndex = index;
- this.createChild(child, mountImage);
- this._renderedChildren = this._renderedChildren || {};
- this._renderedChildren[name] = child;
- },
-
- /**
- * Unmounts a rendered child by name.
- *
- * NOTE: This is part of `updateChildren` and is here for readability.
- *
- * @param {ReactComponent} child Component to unmount.
- * @param {string} name Name of the child in `this._renderedChildren`.
- * @private
- */
- _unmountChildByName: function(child, name) {
- this.removeChild(child);
- child._mountIndex = null;
- child.unmountComponent();
- delete this._renderedChildren[name];
- }
-
- }
-
-};
-
-module.exports = ReactMultiChild;
-
-},{"./ReactComponent":31,"./ReactMultiChildUpdateTypes":63,"./flattenChildren":105,"./instantiateReactComponent":119,"./shouldUpdateReactComponent":140}],63:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactMultiChildUpdateTypes
- */
-
-"use strict";
-
-var keyMirror = _dereq_("./keyMirror");
-
-/**
- * When a component's children are updated, a series of update configuration
- * objects are created in order to batch and serialize the required changes.
- *
- * Enumerates all the possible types of update configurations.
- *
- * @internal
- */
-var ReactMultiChildUpdateTypes = keyMirror({
- INSERT_MARKUP: null,
- MOVE_EXISTING: null,
- REMOVE_NODE: null,
- TEXT_CONTENT: null
-});
-
-module.exports = ReactMultiChildUpdateTypes;
-
-},{"./keyMirror":126}],64:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactOwner
- */
-
-"use strict";
-
-var emptyObject = _dereq_("./emptyObject");
-var invariant = _dereq_("./invariant");
-
-/**
- * ReactOwners are capable of storing references to owned components.
- *
- * All components are capable of //being// referenced by owner components, but
- * only ReactOwner components are capable of //referencing// owned components.
- * The named reference is known as a "ref".
- *
- * Refs are available when mounted and updated during reconciliation.
- *
- * var MyComponent = React.createClass({
- * render: function() {
- * return (
- * <div onClick={this.handleClick}>
- * <CustomComponent ref="custom" />
- * </div>
- * );
- * },
- * handleClick: function() {
- * this.refs.custom.handleClick();
- * },
- * componentDidMount: function() {
- * this.refs.custom.initialize();
- * }
- * });
- *
- * Refs should rarely be used. When refs are used, they should only be done to
- * control data that is not handled by React's data flow.
- *
- * @class ReactOwner
- */
-var ReactOwner = {
-
- /**
- * @param {?object} object
- * @return {boolean} True if `object` is a valid owner.
- * @final
- */
- isValidOwner: function(object) {
- return !!(
- object &&
- typeof object.attachRef === 'function' &&
- typeof object.detachRef === 'function'
- );
- },
-
- /**
- * Adds a component by ref to an owner component.
- *
- * @param {ReactComponent} component Component to reference.
- * @param {string} ref Name by which to refer to the component.
- * @param {ReactOwner} owner Component on which to record the ref.
- * @final
- * @internal
- */
- addComponentAsRefTo: function(component, ref, owner) {
- ("production" !== "development" ? invariant(
- ReactOwner.isValidOwner(owner),
- 'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' +
- 'usually means that you\'re trying to add a ref to a component that ' +
- 'doesn\'t have an owner (that is, was not created inside of another ' +
- 'component\'s `render` method). Try rendering this component inside of ' +
- 'a new top-level component which will hold the ref.'
- ) : invariant(ReactOwner.isValidOwner(owner)));
- owner.attachRef(ref, component);
- },
-
- /**
- * Removes a component by ref from an owner component.
- *
- * @param {ReactComponent} component Component to dereference.
- * @param {string} ref Name of the ref to remove.
- * @param {ReactOwner} owner Component on which the ref is recorded.
- * @final
- * @internal
- */
- removeComponentAsRefFrom: function(component, ref, owner) {
- ("production" !== "development" ? invariant(
- ReactOwner.isValidOwner(owner),
- 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' +
- 'usually means that you\'re trying to remove a ref to a component that ' +
- 'doesn\'t have an owner (that is, was not created inside of another ' +
- 'component\'s `render` method). Try rendering this component inside of ' +
- 'a new top-level component which will hold the ref.'
- ) : invariant(ReactOwner.isValidOwner(owner)));
- // Check that `component` is still the current ref because we do not want to
- // detach the ref if another component stole it.
- if (owner.refs[ref] === component) {
- owner.detachRef(ref);
- }
- },
-
- /**
- * A ReactComponent must mix this in to have refs.
- *
- * @lends {ReactOwner.prototype}
- */
- Mixin: {
-
- construct: function() {
- this.refs = emptyObject;
- },
-
- /**
- * Lazily allocates the refs object and stores `component` as `ref`.
- *
- * @param {string} ref Reference name.
- * @param {component} component Component to store as `ref`.
- * @final
- * @private
- */
- attachRef: function(ref, component) {
- ("production" !== "development" ? invariant(
- component.isOwnedBy(this),
- 'attachRef(%s, ...): Only a component\'s owner can store a ref to it.',
- ref
- ) : invariant(component.isOwnedBy(this)));
- var refs = this.refs === emptyObject ? (this.refs = {}) : this.refs;
- refs[ref] = component;
- },
-
- /**
- * Detaches a reference name.
- *
- * @param {string} ref Name to dereference.
- * @final
- * @private
- */
- detachRef: function(ref) {
- delete this.refs[ref];
- }
-
- }
-
-};
-
-module.exports = ReactOwner;
-
-},{"./emptyObject":103,"./invariant":120}],65:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactPerf
- * @typechecks static-only
- */
-
-"use strict";
-
-/**
- * ReactPerf is a general AOP system designed to measure performance. This
- * module only has the hooks: see ReactDefaultPerf for the analysis tool.
- */
-var ReactPerf = {
- /**
- * Boolean to enable/disable measurement. Set to false by default to prevent
- * accidental logging and perf loss.
- */
- enableMeasure: false,
-
- /**
- * Holds onto the measure function in use. By default, don't measure
- * anything, but we'll override this if we inject a measure function.
- */
- storedMeasure: _noMeasure,
-
- /**
- * Use this to wrap methods you want to measure. Zero overhead in production.
- *
- * @param {string} objName
- * @param {string} fnName
- * @param {function} func
- * @return {function}
- */
- measure: function(objName, fnName, func) {
- if ("production" !== "development") {
- var measuredFunc = null;
- return function() {
- if (ReactPerf.enableMeasure) {
- if (!measuredFunc) {
- measuredFunc = ReactPerf.storedMeasure(objName, fnName, func);
- }
- return measuredFunc.apply(this, arguments);
- }
- return func.apply(this, arguments);
- };
- }
- return func;
- },
-
- injection: {
- /**
- * @param {function} measure
- */
- injectMeasure: function(measure) {
- ReactPerf.storedMeasure = measure;
- }
- }
-};
-
-/**
- * Simply passes through the measured function, without measuring it.
- *
- * @param {string} objName
- * @param {string} fnName
- * @param {function} func
- * @return {function}
- */
-function _noMeasure(objName, fnName, func) {
- return func;
-}
-
-module.exports = ReactPerf;
-
-},{}],66:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactPropTransferer
- */
-
-"use strict";
-
-var emptyFunction = _dereq_("./emptyFunction");
-var invariant = _dereq_("./invariant");
-var joinClasses = _dereq_("./joinClasses");
-var merge = _dereq_("./merge");
-
-/**
- * Creates a transfer strategy that will merge prop values using the supplied
- * `mergeStrategy`. If a prop was previously unset, this just sets it.
- *
- * @param {function} mergeStrategy
- * @return {function}
- */
-function createTransferStrategy(mergeStrategy) {
- return function(props, key, value) {
- if (!props.hasOwnProperty(key)) {
- props[key] = value;
- } else {
- props[key] = mergeStrategy(props[key], value);
- }
- };
-}
-
-var transferStrategyMerge = createTransferStrategy(function(a, b) {
- // `merge` overrides the first object's (`props[key]` above) keys using the
- // second object's (`value`) keys. An object's style's existing `propA` would
- // get overridden. Flip the order here.
- return merge(b, a);
-});
-
-/**
- * Transfer strategies dictate how props are transferred by `transferPropsTo`.
- * NOTE: if you add any more exceptions to this list you should be sure to
- * update `cloneWithProps()` accordingly.
- */
-var TransferStrategies = {
- /**
- * Never transfer `children`.
- */
- children: emptyFunction,
- /**
- * Transfer the `className` prop by merging them.
- */
- className: createTransferStrategy(joinClasses),
- /**
- * Never transfer the `key` prop.
- */
- key: emptyFunction,
- /**
- * Never transfer the `ref` prop.
- */
- ref: emptyFunction,
- /**
- * Transfer the `style` prop (which is an object) by merging them.
- */
- style: transferStrategyMerge
-};
-
-/**
- * Mutates the first argument by transferring the properties from the second
- * argument.
- *
- * @param {object} props
- * @param {object} newProps
- * @return {object}
- */
-function transferInto(props, newProps) {
- for (var thisKey in newProps) {
- if (!newProps.hasOwnProperty(thisKey)) {
- continue;
- }
-
- var transferStrategy = TransferStrategies[thisKey];
-
- if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) {
- transferStrategy(props, thisKey, newProps[thisKey]);
- } else if (!props.hasOwnProperty(thisKey)) {
- props[thisKey] = newProps[thisKey];
- }
- }
- return props;
-}
-
-/**
- * ReactPropTransferer are capable of transferring props to another component
- * using a `transferPropsTo` method.
- *
- * @class ReactPropTransferer
- */
-var ReactPropTransferer = {
-
- TransferStrategies: TransferStrategies,
-
- /**
- * Merge two props objects using TransferStrategies.
- *
- * @param {object} oldProps original props (they take precedence)
- * @param {object} newProps new props to merge in
- * @return {object} a new object containing both sets of props merged.
- */
- mergeProps: function(oldProps, newProps) {
- return transferInto(merge(oldProps), newProps);
- },
-
- /**
- * @lends {ReactPropTransferer.prototype}
- */
- Mixin: {
-
- /**
- * Transfer props from this component to a target component.
- *
- * Props that do not have an explicit transfer strategy will be transferred
- * only if the target component does not already have the prop set.
- *
- * This is usually used to pass down props to a returned root component.
- *
- * @param {ReactDescriptor} descriptor Component receiving the properties.
- * @return {ReactDescriptor} The supplied `component`.
- * @final
- * @protected
- */
- transferPropsTo: function(descriptor) {
- ("production" !== "development" ? invariant(
- descriptor._owner === this,
- '%s: You can\'t call transferPropsTo() on a component that you ' +
- 'don\'t own, %s. This usually means you are calling ' +
- 'transferPropsTo() on a component passed in as props or children.',
- this.constructor.displayName,
- descriptor.type.displayName
- ) : invariant(descriptor._owner === this));
-
- // Because descriptors are immutable we have to merge into the existing
- // props object rather than clone it.
- transferInto(descriptor.props, this.props);
-
- return descriptor;
- }
-
- }
-};
-
-module.exports = ReactPropTransferer;
-
-},{"./emptyFunction":102,"./invariant":120,"./joinClasses":125,"./merge":130}],67:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactPropTypeLocationNames
- */
-
-"use strict";
-
-var ReactPropTypeLocationNames = {};
-
-if ("production" !== "development") {
- ReactPropTypeLocationNames = {
- prop: 'prop',
- context: 'context',
- childContext: 'child context'
- };
-}
-
-module.exports = ReactPropTypeLocationNames;
-
-},{}],68:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactPropTypeLocations
- */
-
-"use strict";
-
-var keyMirror = _dereq_("./keyMirror");
-
-var ReactPropTypeLocations = keyMirror({
- prop: null,
- context: null,
- childContext: null
-});
-
-module.exports = ReactPropTypeLocations;
-
-},{"./keyMirror":126}],69:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactPropTypes
- */
-
-"use strict";
-
-var ReactDescriptor = _dereq_("./ReactDescriptor");
-var ReactPropTypeLocationNames = _dereq_("./ReactPropTypeLocationNames");
-
-var emptyFunction = _dereq_("./emptyFunction");
-
-/**
- * Collection of methods that allow declaration and validation of props that are
- * supplied to React components. Example usage:
- *
- * var Props = require('ReactPropTypes');
- * var MyArticle = React.createClass({
- * propTypes: {
- * // An optional string prop named "description".
- * description: Props.string,
- *
- * // A required enum prop named "category".
- * category: Props.oneOf(['News','Photos']).isRequired,
- *
- * // A prop named "dialog" that requires an instance of Dialog.
- * dialog: Props.instanceOf(Dialog).isRequired
- * },
- * render: function() { ... }
- * });
- *
- * A more formal specification of how these methods are used:
- *
- * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
- * decl := ReactPropTypes.{type}(.isRequired)?
- *
- * Each and every declaration produces a function with the same signature. This
- * allows the creation of custom validation functions. For example:
- *
- * var MyLink = React.createClass({
- * propTypes: {
- * // An optional string or URI prop named "href".
- * href: function(props, propName, componentName) {
- * var propValue = props[propName];
- * if (propValue != null && typeof propValue !== 'string' &&
- * !(propValue instanceof URI)) {
- * return new Error(
- * 'Expected a string or an URI for ' + propName + ' in ' +
- * componentName
- * );
- * }
- * }
- * },
- * render: function() {...}
- * });
- *
- * @internal
- */
-
-var ANONYMOUS = '<<anonymous>>';
-
-var ReactPropTypes = {
- array: createPrimitiveTypeChecker('array'),
- bool: createPrimitiveTypeChecker('boolean'),
- func: createPrimitiveTypeChecker('function'),
- number: createPrimitiveTypeChecker('number'),
- object: createPrimitiveTypeChecker('object'),
- string: createPrimitiveTypeChecker('string'),
-
- any: createAnyTypeChecker(),
- arrayOf: createArrayOfTypeChecker,
- component: createComponentTypeChecker(),
- instanceOf: createInstanceTypeChecker,
- objectOf: createObjectOfTypeChecker,
- oneOf: createEnumTypeChecker,
- oneOfType: createUnionTypeChecker,
- renderable: createRenderableTypeChecker(),
- shape: createShapeTypeChecker
-};
-
-function createChainableTypeChecker(validate) {
- function checkType(isRequired, props, propName, componentName, location) {
- componentName = componentName || ANONYMOUS;
- if (props[propName] == null) {
- var locationName = ReactPropTypeLocationNames[location];
- if (isRequired) {
- return new Error(
- ("Required " + locationName + " `" + propName + "` was not specified in ")+
- ("`" + componentName + "`.")
- );
- }
- } else {
- return validate(props, propName, componentName, location);
- }
- }
-
- var chainedCheckType = checkType.bind(null, false);
- chainedCheckType.isRequired = checkType.bind(null, true);
-
- return chainedCheckType;
-}
-
-function createPrimitiveTypeChecker(expectedType) {
- function validate(props, propName, componentName, location) {
- var propValue = props[propName];
- var propType = getPropType(propValue);
- if (propType !== expectedType) {
- var locationName = ReactPropTypeLocationNames[location];
- // `propValue` being instance of, say, date/regexp, pass the 'object'
- // check, but we can offer a more precise error message here rather than
- // 'of type `object`'.
- var preciseType = getPreciseType(propValue);
-
- return new Error(
- ("Invalid " + locationName + " `" + propName + "` of type `" + preciseType + "` ") +
- ("supplied to `" + componentName + "`, expected `" + expectedType + "`.")
- );
- }
- }
- return createChainableTypeChecker(validate);
-}
-
-function createAnyTypeChecker() {
- return createChainableTypeChecker(emptyFunction.thatReturns());
-}
-
-function createArrayOfTypeChecker(typeChecker) {
- function validate(props, propName, componentName, location) {
- var propValue = props[propName];
- if (!Array.isArray(propValue)) {
- var locationName = ReactPropTypeLocationNames[location];
- var propType = getPropType(propValue);
- return new Error(
- ("Invalid " + locationName + " `" + propName + "` of type ") +
- ("`" + propType + "` supplied to `" + componentName + "`, expected an array.")
- );
- }
- for (var i = 0; i < propValue.length; i++) {
- var error = typeChecker(propValue, i, componentName, location);
- if (error instanceof Error) {
- return error;
- }
- }
- }
- return createChainableTypeChecker(validate);
-}
-
-function createComponentTypeChecker() {
- function validate(props, propName, componentName, location) {
- if (!ReactDescriptor.isValidDescriptor(props[propName])) {
- var locationName = ReactPropTypeLocationNames[location];
- return new Error(
- ("Invalid " + locationName + " `" + propName + "` supplied to ") +
- ("`" + componentName + "`, expected a React component.")
- );
- }
- }
- return createChainableTypeChecker(validate);
-}
-
-function createInstanceTypeChecker(expectedClass) {
- function validate(props, propName, componentName, location) {
- if (!(props[propName] instanceof expectedClass)) {
- var locationName = ReactPropTypeLocationNames[location];
- var expectedClassName = expectedClass.name || ANONYMOUS;
- return new Error(
- ("Invalid " + locationName + " `" + propName + "` supplied to ") +
- ("`" + componentName + "`, expected instance of `" + expectedClassName + "`.")
- );
- }
- }
- return createChainableTypeChecker(validate);
-}
-
-function createEnumTypeChecker(expectedValues) {
- function validate(props, propName, componentName, location) {
- var propValue = props[propName];
- for (var i = 0; i < expectedValues.length; i++) {
- if (propValue === expectedValues[i]) {
- return;
- }
- }
-
- var locationName = ReactPropTypeLocationNames[location];
- var valuesString = JSON.stringify(expectedValues);
- return new Error(
- ("Invalid " + locationName + " `" + propName + "` of value `" + propValue + "` ") +
- ("supplied to `" + componentName + "`, expected one of " + valuesString + ".")
- );
- }
- return createChainableTypeChecker(validate);
-}
-
-function createObjectOfTypeChecker(typeChecker) {
- function validate(props, propName, componentName, location) {
- var propValue = props[propName];
- var propType = getPropType(propValue);
- if (propType !== 'object') {
- var locationName = ReactPropTypeLocationNames[location];
- return new Error(
- ("Invalid " + locationName + " `" + propName + "` of type ") +
- ("`" + propType + "` supplied to `" + componentName + "`, expected an object.")
- );
- }
- for (var key in propValue) {
- if (propValue.hasOwnProperty(key)) {
- var error = typeChecker(propValue, key, componentName, location);
- if (error instanceof Error) {
- return error;
- }
- }
- }
- }
- return createChainableTypeChecker(validate);
-}
-
-function createUnionTypeChecker(arrayOfTypeCheckers) {
- function validate(props, propName, componentName, location) {
- for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
- var checker = arrayOfTypeCheckers[i];
- if (checker(props, propName, componentName, location) == null) {
- return;
- }
- }
-
- var locationName = ReactPropTypeLocationNames[location];
- return new Error(
- ("Invalid " + locationName + " `" + propName + "` supplied to ") +
- ("`" + componentName + "`.")
- );
- }
- return createChainableTypeChecker(validate);
-}
-
-function createRenderableTypeChecker() {
- function validate(props, propName, componentName, location) {
- if (!isRenderable(props[propName])) {
- var locationName = ReactPropTypeLocationNames[location];
- return new Error(
- ("Invalid " + locationName + " `" + propName + "` supplied to ") +
- ("`" + componentName + "`, expected a renderable prop.")
- );
- }
- }
- return createChainableTypeChecker(validate);
-}
-
-function createShapeTypeChecker(shapeTypes) {
- function validate(props, propName, componentName, location) {
- var propValue = props[propName];
- var propType = getPropType(propValue);
- if (propType !== 'object') {
- var locationName = ReactPropTypeLocationNames[location];
- return new Error(
- ("Invalid " + locationName + " `" + propName + "` of type `" + propType + "` ") +
- ("supplied to `" + componentName + "`, expected `object`.")
- );
- }
- for (var key in shapeTypes) {
- var checker = shapeTypes[key];
- if (!checker) {
- continue;
- }
- var error = checker(propValue, key, componentName, location);
- if (error) {
- return error;
- }
- }
- }
- return createChainableTypeChecker(validate, 'expected `object`');
-}
-
-function isRenderable(propValue) {
- switch(typeof propValue) {
- // TODO: this was probably written with the assumption that we're not
- // returning `this.props.component` directly from `render`. This is
- // currently not supported but we should, to make it consistent.
- case 'number':
- case 'string':
- return true;
- case 'boolean':
- return !propValue;
- case 'object':
- if (Array.isArray(propValue)) {
- return propValue.every(isRenderable);
- }
- if (ReactDescriptor.isValidDescriptor(propValue)) {
- return true;
- }
- for (var k in propValue) {
- if (!isRenderable(propValue[k])) {
- return false;
- }
- }
- return true;
- default:
- return false;
- }
-}
-
-// Equivalent of `typeof` but with special handling for array and regexp.
-function getPropType(propValue) {
- var propType = typeof propValue;
- if (Array.isArray(propValue)) {
- return 'array';
- }
- if (propValue instanceof RegExp) {
- // Old webkits (at least until Android 4.0) return 'function' rather than
- // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
- // passes PropTypes.object.
- return 'object';
- }
- return propType;
-}
-
-// This handles more types than `getPropType`. Only used for error messages.
-// See `createPrimitiveTypeChecker`.
-function getPreciseType(propValue) {
- var propType = getPropType(propValue);
- if (propType === 'object') {
- if (propValue instanceof Date) {
- return 'date';
- } else if (propValue instanceof RegExp) {
- return 'regexp';
- }
- }
- return propType;
-}
-
-module.exports = ReactPropTypes;
-
-},{"./ReactDescriptor":51,"./ReactPropTypeLocationNames":67,"./emptyFunction":102}],70:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactPutListenerQueue
- */
-
-"use strict";
-
-var PooledClass = _dereq_("./PooledClass");
-var ReactBrowserEventEmitter = _dereq_("./ReactBrowserEventEmitter");
-
-var mixInto = _dereq_("./mixInto");
-
-function ReactPutListenerQueue() {
- this.listenersToPut = [];
-}
-
-mixInto(ReactPutListenerQueue, {
- enqueuePutListener: function(rootNodeID, propKey, propValue) {
- this.listenersToPut.push({
- rootNodeID: rootNodeID,
- propKey: propKey,
- propValue: propValue
- });
- },
-
- putListeners: function() {
- for (var i = 0; i < this.listenersToPut.length; i++) {
- var listenerToPut = this.listenersToPut[i];
- ReactBrowserEventEmitter.putListener(
- listenerToPut.rootNodeID,
- listenerToPut.propKey,
- listenerToPut.propValue
- );
- }
- },
-
- reset: function() {
- this.listenersToPut.length = 0;
- },
-
- destructor: function() {
- this.reset();
- }
-});
-
-PooledClass.addPoolingTo(ReactPutListenerQueue);
-
-module.exports = ReactPutListenerQueue;
-
-},{"./PooledClass":26,"./ReactBrowserEventEmitter":29,"./mixInto":133}],71:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactReconcileTransaction
- * @typechecks static-only
- */
-
-"use strict";
-
-var CallbackQueue = _dereq_("./CallbackQueue");
-var PooledClass = _dereq_("./PooledClass");
-var ReactBrowserEventEmitter = _dereq_("./ReactBrowserEventEmitter");
-var ReactInputSelection = _dereq_("./ReactInputSelection");
-var ReactPutListenerQueue = _dereq_("./ReactPutListenerQueue");
-var Transaction = _dereq_("./Transaction");
-
-var mixInto = _dereq_("./mixInto");
-
-/**
- * Ensures that, when possible, the selection range (currently selected text
- * input) is not disturbed by performing the transaction.
- */
-var SELECTION_RESTORATION = {
- /**
- * @return {Selection} Selection information.
- */
- initialize: ReactInputSelection.getSelectionInformation,
- /**
- * @param {Selection} sel Selection information returned from `initialize`.
- */
- close: ReactInputSelection.restoreSelection
-};
-
-/**
- * Suppresses events (blur/focus) that could be inadvertently dispatched due to
- * high level DOM manipulations (like temporarily removing a text input from the
- * DOM).
- */
-var EVENT_SUPPRESSION = {
- /**
- * @return {boolean} The enabled status of `ReactBrowserEventEmitter` before
- * the reconciliation.
- */
- initialize: function() {
- var currentlyEnabled = ReactBrowserEventEmitter.isEnabled();
- ReactBrowserEventEmitter.setEnabled(false);
- return currentlyEnabled;
- },
-
- /**
- * @param {boolean} previouslyEnabled Enabled status of
- * `ReactBrowserEventEmitter` before the reconciliation occured. `close`
- * restores the previous value.
- */
- close: function(previouslyEnabled) {
- ReactBrowserEventEmitter.setEnabled(previouslyEnabled);
- }
-};
-
-/**
- * Provides a queue for collecting `componentDidMount` and
- * `componentDidUpdate` callbacks during the the transaction.
- */
-var ON_DOM_READY_QUEUEING = {
- /**
- * Initializes the internal `onDOMReady` queue.
- */
- initialize: function() {
- this.reactMountReady.reset();
- },
-
- /**
- * After DOM is flushed, invoke all registered `onDOMReady` callbacks.
- */
- close: function() {
- this.reactMountReady.notifyAll();
- }
-};
-
-var PUT_LISTENER_QUEUEING = {
- initialize: function() {
- this.putListenerQueue.reset();
- },
-
- close: function() {
- this.putListenerQueue.putListeners();
- }
-};
-
-/**
- * Executed within the scope of the `Transaction` instance. Consider these as
- * being member methods, but with an implied ordering while being isolated from
- * each other.
- */
-var TRANSACTION_WRAPPERS = [
- PUT_LISTENER_QUEUEING,
- SELECTION_RESTORATION,
- EVENT_SUPPRESSION,
- ON_DOM_READY_QUEUEING
-];
-
-/**
- * Currently:
- * - The order that these are listed in the transaction is critical:
- * - Suppresses events.
- * - Restores selection range.
- *
- * Future:
- * - Restore document/overflow scroll positions that were unintentionally
- * modified via DOM insertions above the top viewport boundary.
- * - Implement/integrate with customized constraint based layout system and keep
- * track of which dimensions must be remeasured.
- *
- * @class ReactReconcileTransaction
- */
-function ReactReconcileTransaction() {
- this.reinitializeTransaction();
- // Only server-side rendering really needs this option (see
- // `ReactServerRendering`), but server-side uses
- // `ReactServerRenderingTransaction` instead. This option is here so that it's
- // accessible and defaults to false when `ReactDOMComponent` and
- // `ReactTextComponent` checks it in `mountComponent`.`
- this.renderToStaticMarkup = false;
- this.reactMountReady = CallbackQueue.getPooled(null);
- this.putListenerQueue = ReactPutListenerQueue.getPooled();
-}
-
-var Mixin = {
- /**
- * @see Transaction
- * @abstract
- * @final
- * @return {array<object>} List of operation wrap proceedures.
- * TODO: convert to array<TransactionWrapper>
- */
- getTransactionWrappers: function() {
- return TRANSACTION_WRAPPERS;
- },
-
- /**
- * @return {object} The queue to collect `onDOMReady` callbacks with.
- */
- getReactMountReady: function() {
- return this.reactMountReady;
- },
-
- getPutListenerQueue: function() {
- return this.putListenerQueue;
- },
-
- /**
- * `PooledClass` looks for this, and will invoke this before allowing this
- * instance to be resused.
- */
- destructor: function() {
- CallbackQueue.release(this.reactMountReady);
- this.reactMountReady = null;
-
- ReactPutListenerQueue.release(this.putListenerQueue);
- this.putListenerQueue = null;
- }
-};
-
-
-mixInto(ReactReconcileTransaction, Transaction.Mixin);
-mixInto(ReactReconcileTransaction, Mixin);
-
-PooledClass.addPoolingTo(ReactReconcileTransaction);
-
-module.exports = ReactReconcileTransaction;
-
-},{"./CallbackQueue":5,"./PooledClass":26,"./ReactBrowserEventEmitter":29,"./ReactInputSelection":58,"./ReactPutListenerQueue":70,"./Transaction":92,"./mixInto":133}],72:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactRootIndex
- * @typechecks
- */
-
-"use strict";
-
-var ReactRootIndexInjection = {
- /**
- * @param {function} _createReactRootIndex
- */
- injectCreateReactRootIndex: function(_createReactRootIndex) {
- ReactRootIndex.createReactRootIndex = _createReactRootIndex;
- }
-};
-
-var ReactRootIndex = {
- createReactRootIndex: null,
- injection: ReactRootIndexInjection
-};
-
-module.exports = ReactRootIndex;
-
-},{}],73:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @typechecks static-only
- * @providesModule ReactServerRendering
- */
-"use strict";
-
-var ReactDescriptor = _dereq_("./ReactDescriptor");
-var ReactInstanceHandles = _dereq_("./ReactInstanceHandles");
-var ReactMarkupChecksum = _dereq_("./ReactMarkupChecksum");
-var ReactServerRenderingTransaction =
- _dereq_("./ReactServerRenderingTransaction");
-
-var instantiateReactComponent = _dereq_("./instantiateReactComponent");
-var invariant = _dereq_("./invariant");
-
-/**
- * @param {ReactComponent} component
- * @return {string} the HTML markup
- */
-function renderComponentToString(component) {
- ("production" !== "development" ? invariant(
- ReactDescriptor.isValidDescriptor(component),
- 'renderComponentToString(): You must pass a valid ReactComponent.'
- ) : invariant(ReactDescriptor.isValidDescriptor(component)));
-
- ("production" !== "development" ? invariant(
- !(arguments.length === 2 && typeof arguments[1] === 'function'),
- 'renderComponentToString(): This function became synchronous and now ' +
- 'returns the generated markup. Please remove the second parameter.'
- ) : invariant(!(arguments.length === 2 && typeof arguments[1] === 'function')));
-
- var transaction;
- try {
- var id = ReactInstanceHandles.createReactRootID();
- transaction = ReactServerRenderingTransaction.getPooled(false);
-
- return transaction.perform(function() {
- var componentInstance = instantiateReactComponent(component);
- var markup = componentInstance.mountComponent(id, transaction, 0);
- return ReactMarkupChecksum.addChecksumToMarkup(markup);
- }, null);
- } finally {
- ReactServerRenderingTransaction.release(transaction);
- }
-}
-
-/**
- * @param {ReactComponent} component
- * @return {string} the HTML markup, without the extra React ID and checksum
-* (for generating static pages)
- */
-function renderComponentToStaticMarkup(component) {
- ("production" !== "development" ? invariant(
- ReactDescriptor.isValidDescriptor(component),
- 'renderComponentToStaticMarkup(): You must pass a valid ReactComponent.'
- ) : invariant(ReactDescriptor.isValidDescriptor(component)));
-
- var transaction;
- try {
- var id = ReactInstanceHandles.createReactRootID();
- transaction = ReactServerRenderingTransaction.getPooled(true);
-
- return transaction.perform(function() {
- var componentInstance = instantiateReactComponent(component);
- return componentInstance.mountComponent(id, transaction, 0);
- }, null);
- } finally {
- ReactServerRenderingTransaction.release(transaction);
- }
-}
-
-module.exports = {
- renderComponentToString: renderComponentToString,
- renderComponentToStaticMarkup: renderComponentToStaticMarkup
-};
-
-},{"./ReactDescriptor":51,"./ReactInstanceHandles":59,"./ReactMarkupChecksum":60,"./ReactServerRenderingTransaction":74,"./instantiateReactComponent":119,"./invariant":120}],74:[function(_dereq_,module,exports){
-/**
- * Copyright 2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactServerRenderingTransaction
- * @typechecks
- */
-
-"use strict";
-
-var PooledClass = _dereq_("./PooledClass");
-var CallbackQueue = _dereq_("./CallbackQueue");
-var ReactPutListenerQueue = _dereq_("./ReactPutListenerQueue");
-var Transaction = _dereq_("./Transaction");
-
-var emptyFunction = _dereq_("./emptyFunction");
-var mixInto = _dereq_("./mixInto");
-
-/**
- * Provides a `CallbackQueue` queue for collecting `onDOMReady` callbacks
- * during the performing of the transaction.
- */
-var ON_DOM_READY_QUEUEING = {
- /**
- * Initializes the internal `onDOMReady` queue.
- */
- initialize: function() {
- this.reactMountReady.reset();
- },
-
- close: emptyFunction
-};
-
-var PUT_LISTENER_QUEUEING = {
- initialize: function() {
- this.putListenerQueue.reset();
- },
-
- close: emptyFunction
-};
-
-/**
- * Executed within the scope of the `Transaction` instance. Consider these as
- * being member methods, but with an implied ordering while being isolated from
- * each other.
- */
-var TRANSACTION_WRAPPERS = [
- PUT_LISTENER_QUEUEING,
- ON_DOM_READY_QUEUEING
-];
-
-/**
- * @class ReactServerRenderingTransaction
- * @param {boolean} renderToStaticMarkup
- */
-function ReactServerRenderingTransaction(renderToStaticMarkup) {
- this.reinitializeTransaction();
- this.renderToStaticMarkup = renderToStaticMarkup;
- this.reactMountReady = CallbackQueue.getPooled(null);
- this.putListenerQueue = ReactPutListenerQueue.getPooled();
-}
-
-var Mixin = {
- /**
- * @see Transaction
- * @abstract
- * @final
- * @return {array} Empty list of operation wrap proceedures.
- */
- getTransactionWrappers: function() {
- return TRANSACTION_WRAPPERS;
- },
-
- /**
- * @return {object} The queue to collect `onDOMReady` callbacks with.
- */
- getReactMountReady: function() {
- return this.reactMountReady;
- },
-
- getPutListenerQueue: function() {
- return this.putListenerQueue;
- },
-
- /**
- * `PooledClass` looks for this, and will invoke this before allowing this
- * instance to be resused.
- */
- destructor: function() {
- CallbackQueue.release(this.reactMountReady);
- this.reactMountReady = null;
-
- ReactPutListenerQueue.release(this.putListenerQueue);
- this.putListenerQueue = null;
- }
-};
-
-
-mixInto(ReactServerRenderingTransaction, Transaction.Mixin);
-mixInto(ReactServerRenderingTransaction, Mixin);
-
-PooledClass.addPoolingTo(ReactServerRenderingTransaction);
-
-module.exports = ReactServerRenderingTransaction;
-
-},{"./CallbackQueue":5,"./PooledClass":26,"./ReactPutListenerQueue":70,"./Transaction":92,"./emptyFunction":102,"./mixInto":133}],75:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactTextComponent
- * @typechecks static-only
- */
-
-"use strict";
-
-var DOMPropertyOperations = _dereq_("./DOMPropertyOperations");
-var ReactBrowserComponentMixin = _dereq_("./ReactBrowserComponentMixin");
-var ReactComponent = _dereq_("./ReactComponent");
-var ReactDescriptor = _dereq_("./ReactDescriptor");
-
-var escapeTextForBrowser = _dereq_("./escapeTextForBrowser");
-var mixInto = _dereq_("./mixInto");
-
-/**
- * Text nodes violate a couple assumptions that React makes about components:
- *
- * - When mounting text into the DOM, adjacent text nodes are merged.
- * - Text nodes cannot be assigned a React root ID.
- *
- * This component is used to wrap strings in elements so that they can undergo
- * the same reconciliation that is applied to elements.
- *
- * TODO: Investigate representing React components in the DOM with text nodes.
- *
- * @class ReactTextComponent
- * @extends ReactComponent
- * @internal
- */
-var ReactTextComponent = function(descriptor) {
- this.construct(descriptor);
-};
-
-mixInto(ReactTextComponent, ReactComponent.Mixin);
-mixInto(ReactTextComponent, ReactBrowserComponentMixin);
-mixInto(ReactTextComponent, {
-
- /**
- * Creates the markup for this text node. This node is not intended to have
- * any features besides containing text content.
- *
- * @param {string} rootID DOM ID of the root node.
- * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
- * @param {number} mountDepth number of components in the owner hierarchy
- * @return {string} Markup for this text node.
- * @internal
- */
- mountComponent: function(rootID, transaction, mountDepth) {
- ReactComponent.Mixin.mountComponent.call(
- this,
- rootID,
- transaction,
- mountDepth
- );
-
- var escapedText = escapeTextForBrowser(this.props);
-
- if (transaction.renderToStaticMarkup) {
- // Normally we'd wrap this in a `span` for the reasons stated above, but
- // since this is a situation where React won't take over (static pages),
- // we can simply return the text as it is.
- return escapedText;
- }
-
- return (
- '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' +
- escapedText +
- '</span>'
- );
- },
-
- /**
- * Updates this component by updating the text content.
- *
- * @param {object} nextComponent Contains the next text content.
- * @param {ReactReconcileTransaction} transaction
- * @internal
- */
- receiveComponent: function(nextComponent, transaction) {
- var nextProps = nextComponent.props;
- if (nextProps !== this.props) {
- this.props = nextProps;
- ReactComponent.BackendIDOperations.updateTextContentByID(
- this._rootNodeID,
- nextProps
- );
- }
- }
-
-});
-
-module.exports = ReactDescriptor.createFactory(ReactTextComponent);
-
-},{"./DOMPropertyOperations":11,"./ReactBrowserComponentMixin":28,"./ReactComponent":31,"./ReactDescriptor":51,"./escapeTextForBrowser":104,"./mixInto":133}],76:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ReactUpdates
- */
-
-"use strict";
-
-var CallbackQueue = _dereq_("./CallbackQueue");
-var PooledClass = _dereq_("./PooledClass");
-var ReactCurrentOwner = _dereq_("./ReactCurrentOwner");
-var ReactPerf = _dereq_("./ReactPerf");
-var Transaction = _dereq_("./Transaction");
-
-var invariant = _dereq_("./invariant");
-var mixInto = _dereq_("./mixInto");
-var warning = _dereq_("./warning");
-
-var dirtyComponents = [];
-
-var batchingStrategy = null;
-
-function ensureInjected() {
- ("production" !== "development" ? invariant(
- ReactUpdates.ReactReconcileTransaction && batchingStrategy,
- 'ReactUpdates: must inject a reconcile transaction class and batching ' +
- 'strategy'
- ) : invariant(ReactUpdates.ReactReconcileTransaction && batchingStrategy));
-}
-
-var NESTED_UPDATES = {
- initialize: function() {
- this.dirtyComponentsLength = dirtyComponents.length;
- },
- close: function() {
- if (this.dirtyComponentsLength !== dirtyComponents.length) {
- // Additional updates were enqueued by componentDidUpdate handlers or
- // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run
- // these new updates so that if A's componentDidUpdate calls setState on
- // B, B will update before the callback A's updater provided when calling
- // setState.
- dirtyComponents.splice(0, this.dirtyComponentsLength);
- flushBatchedUpdates();
- } else {
- dirtyComponents.length = 0;
- }
- }
-};
-
-var UPDATE_QUEUEING = {
- initialize: function() {
- this.callbackQueue.reset();
- },
- close: function() {
- this.callbackQueue.notifyAll();
- }
-};
-
-var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING];
-
-function ReactUpdatesFlushTransaction() {
- this.reinitializeTransaction();
- this.dirtyComponentsLength = null;
- this.callbackQueue = CallbackQueue.getPooled(null);
- this.reconcileTransaction =
- ReactUpdates.ReactReconcileTransaction.getPooled();
-}
-
-mixInto(ReactUpdatesFlushTransaction, Transaction.Mixin);
-mixInto(ReactUpdatesFlushTransaction, {
- getTransactionWrappers: function() {
- return TRANSACTION_WRAPPERS;
- },
-
- destructor: function() {
- this.dirtyComponentsLength = null;
- CallbackQueue.release(this.callbackQueue);
- this.callbackQueue = null;
- ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction);
- this.reconcileTransaction = null;
- },
-
- perform: function(method, scope, a) {
- // Essentially calls `this.reconcileTransaction.perform(method, scope, a)`
- // with this transaction's wrappers around it.
- return Transaction.Mixin.perform.call(
- this,
- this.reconcileTransaction.perform,
- this.reconcileTransaction,
- method,
- scope,
- a
- );
- }
-});
-
-PooledClass.addPoolingTo(ReactUpdatesFlushTransaction);
-
-function batchedUpdates(callback, a, b) {
- ensureInjected();
- batchingStrategy.batchedUpdates(callback, a, b);
-}
-
-/**
- * Array comparator for ReactComponents by owner depth
- *
- * @param {ReactComponent} c1 first component you're comparing
- * @param {ReactComponent} c2 second component you're comparing
- * @return {number} Return value usable by Array.prototype.sort().
- */
-function mountDepthComparator(c1, c2) {
- return c1._mountDepth - c2._mountDepth;
-}
-
-function runBatchedUpdates(transaction) {
- var len = transaction.dirtyComponentsLength;
- ("production" !== "development" ? invariant(
- len === dirtyComponents.length,
- 'Expected flush transaction\'s stored dirty-components length (%s) to ' +
- 'match dirty-components array length (%s).',
- len,
- dirtyComponents.length
- ) : invariant(len === dirtyComponents.length));
-
- // Since reconciling a component higher in the owner hierarchy usually (not
- // always -- see shouldComponentUpdate()) will reconcile children, reconcile
- // them before their children by sorting the array.
- dirtyComponents.sort(mountDepthComparator);
-
- for (var i = 0; i < len; i++) {
- // If a component is unmounted before pending changes apply, ignore them
- // TODO: Queue unmounts in the same list to avoid this happening at all
- var component = dirtyComponents[i];
- if (component.isMounted()) {
- // If performUpdateIfNecessary happens to enqueue any new updates, we
- // shouldn't execute the callbacks until the next render happens, so
- // stash the callbacks first
- var callbacks = component._pendingCallbacks;
- component._pendingCallbacks = null;
- component.performUpdateIfNecessary(transaction.reconcileTransaction);
-
- if (callbacks) {
- for (var j = 0; j < callbacks.length; j++) {
- transaction.callbackQueue.enqueue(
- callbacks[j],
- component
- );
- }
- }
- }
- }
-}
-
-var flushBatchedUpdates = ReactPerf.measure(
- 'ReactUpdates',
- 'flushBatchedUpdates',
- function() {
- // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
- // array and perform any updates enqueued by mount-ready handlers (i.e.,
- // componentDidUpdate) but we need to check here too in order to catch
- // updates enqueued by setState callbacks.
- while (dirtyComponents.length) {
- var transaction = ReactUpdatesFlushTransaction.getPooled();
- transaction.perform(runBatchedUpdates, null, transaction);
- ReactUpdatesFlushTransaction.release(transaction);
- }
- }
-);
-
-/**
- * Mark a component as needing a rerender, adding an optional callback to a
- * list of functions which will be executed once the rerender occurs.
- */
-function enqueueUpdate(component, callback) {
- ("production" !== "development" ? invariant(
- !callback || typeof callback === "function",
- 'enqueueUpdate(...): You called `setProps`, `replaceProps`, ' +
- '`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
- 'isn\'t callable.'
- ) : invariant(!callback || typeof callback === "function"));
- ensureInjected();
-
- // Various parts of our code (such as ReactCompositeComponent's
- // _renderValidatedComponent) assume that calls to render aren't nested;
- // verify that that's the case. (This is called by each top-level update
- // function, like setProps, setState, forceUpdate, etc.; creation and
- // destruction of top-level components is guarded in ReactMount.)
- ("production" !== "development" ? warning(
- ReactCurrentOwner.current == null,
- 'enqueueUpdate(): Render methods should be a pure function of props ' +
- 'and state; triggering nested component updates from render is not ' +
- 'allowed. If necessary, trigger nested updates in ' +
- 'componentDidUpdate.'
- ) : null);
-
- if (!batchingStrategy.isBatchingUpdates) {
- batchingStrategy.batchedUpdates(enqueueUpdate, component, callback);
- return;
- }
-
- dirtyComponents.push(component);
-
- if (callback) {
- if (component._pendingCallbacks) {
- component._pendingCallbacks.push(callback);
- } else {
- component._pendingCallbacks = [callback];
- }
- }
-}
-
-var ReactUpdatesInjection = {
- injectReconcileTransaction: function(ReconcileTransaction) {
- ("production" !== "development" ? invariant(
- ReconcileTransaction,
- 'ReactUpdates: must provide a reconcile transaction class'
- ) : invariant(ReconcileTransaction));
- ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;
- },
-
- injectBatchingStrategy: function(_batchingStrategy) {
- ("production" !== "development" ? invariant(
- _batchingStrategy,
- 'ReactUpdates: must provide a batching strategy'
- ) : invariant(_batchingStrategy));
- ("production" !== "development" ? invariant(
- typeof _batchingStrategy.batchedUpdates === 'function',
- 'ReactUpdates: must provide a batchedUpdates() function'
- ) : invariant(typeof _batchingStrategy.batchedUpdates === 'function'));
- ("production" !== "development" ? invariant(
- typeof _batchingStrategy.isBatchingUpdates === 'boolean',
- 'ReactUpdates: must provide an isBatchingUpdates boolean attribute'
- ) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean'));
- batchingStrategy = _batchingStrategy;
- }
-};
-
-var ReactUpdates = {
- /**
- * React references `ReactReconcileTransaction` using this property in order
- * to allow dependency injection.
- *
- * @internal
- */
- ReactReconcileTransaction: null,
-
- batchedUpdates: batchedUpdates,
- enqueueUpdate: enqueueUpdate,
- flushBatchedUpdates: flushBatchedUpdates,
- injection: ReactUpdatesInjection
-};
-
-module.exports = ReactUpdates;
-
-},{"./CallbackQueue":5,"./PooledClass":26,"./ReactCurrentOwner":35,"./ReactPerf":65,"./Transaction":92,"./invariant":120,"./mixInto":133,"./warning":143}],77:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SVGDOMPropertyConfig
- */
-
-/*jslint bitwise: true*/
-
-"use strict";
-
-var DOMProperty = _dereq_("./DOMProperty");
-
-var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE;
-
-var SVGDOMPropertyConfig = {
- Properties: {
- cx: MUST_USE_ATTRIBUTE,
- cy: MUST_USE_ATTRIBUTE,
- d: MUST_USE_ATTRIBUTE,
- dx: MUST_USE_ATTRIBUTE,
- dy: MUST_USE_ATTRIBUTE,
- fill: MUST_USE_ATTRIBUTE,
- fillOpacity: MUST_USE_ATTRIBUTE,
- fontFamily: MUST_USE_ATTRIBUTE,
- fontSize: MUST_USE_ATTRIBUTE,
- fx: MUST_USE_ATTRIBUTE,
- fy: MUST_USE_ATTRIBUTE,
- gradientTransform: MUST_USE_ATTRIBUTE,
- gradientUnits: MUST_USE_ATTRIBUTE,
- markerEnd: MUST_USE_ATTRIBUTE,
- markerMid: MUST_USE_ATTRIBUTE,
- markerStart: MUST_USE_ATTRIBUTE,
- offset: MUST_USE_ATTRIBUTE,
- opacity: MUST_USE_ATTRIBUTE,
- patternContentUnits: MUST_USE_ATTRIBUTE,
- patternUnits: MUST_USE_ATTRIBUTE,
- points: MUST_USE_ATTRIBUTE,
- preserveAspectRatio: MUST_USE_ATTRIBUTE,
- r: MUST_USE_ATTRIBUTE,
- rx: MUST_USE_ATTRIBUTE,
- ry: MUST_USE_ATTRIBUTE,
- spreadMethod: MUST_USE_ATTRIBUTE,
- stopColor: MUST_USE_ATTRIBUTE,
- stopOpacity: MUST_USE_ATTRIBUTE,
- stroke: MUST_USE_ATTRIBUTE,
- strokeDasharray: MUST_USE_ATTRIBUTE,
- strokeLinecap: MUST_USE_ATTRIBUTE,
- strokeOpacity: MUST_USE_ATTRIBUTE,
- strokeWidth: MUST_USE_ATTRIBUTE,
- textAnchor: MUST_USE_ATTRIBUTE,
- transform: MUST_USE_ATTRIBUTE,
- version: MUST_USE_ATTRIBUTE,
- viewBox: MUST_USE_ATTRIBUTE,
- x1: MUST_USE_ATTRIBUTE,
- x2: MUST_USE_ATTRIBUTE,
- x: MUST_USE_ATTRIBUTE,
- y1: MUST_USE_ATTRIBUTE,
- y2: MUST_USE_ATTRIBUTE,
- y: MUST_USE_ATTRIBUTE
- },
- DOMAttributeNames: {
- fillOpacity: 'fill-opacity',
- fontFamily: 'font-family',
- fontSize: 'font-size',
- gradientTransform: 'gradientTransform',
- gradientUnits: 'gradientUnits',
- markerEnd: 'marker-end',
- markerMid: 'marker-mid',
- markerStart: 'marker-start',
- patternContentUnits: 'patternContentUnits',
- patternUnits: 'patternUnits',
- preserveAspectRatio: 'preserveAspectRatio',
- spreadMethod: 'spreadMethod',
- stopColor: 'stop-color',
- stopOpacity: 'stop-opacity',
- strokeDasharray: 'stroke-dasharray',
- strokeLinecap: 'stroke-linecap',
- strokeOpacity: 'stroke-opacity',
- strokeWidth: 'stroke-width',
- textAnchor: 'text-anchor',
- viewBox: 'viewBox'
- }
-};
-
-module.exports = SVGDOMPropertyConfig;
-
-},{"./DOMProperty":10}],78:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SelectEventPlugin
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-var EventPropagators = _dereq_("./EventPropagators");
-var ReactInputSelection = _dereq_("./ReactInputSelection");
-var SyntheticEvent = _dereq_("./SyntheticEvent");
-
-var getActiveElement = _dereq_("./getActiveElement");
-var isTextInputElement = _dereq_("./isTextInputElement");
-var keyOf = _dereq_("./keyOf");
-var shallowEqual = _dereq_("./shallowEqual");
-
-var topLevelTypes = EventConstants.topLevelTypes;
-
-var eventTypes = {
- select: {
- phasedRegistrationNames: {
- bubbled: keyOf({onSelect: null}),
- captured: keyOf({onSelectCapture: null})
- },
- dependencies: [
- topLevelTypes.topBlur,
- topLevelTypes.topContextMenu,
- topLevelTypes.topFocus,
- topLevelTypes.topKeyDown,
- topLevelTypes.topMouseDown,
- topLevelTypes.topMouseUp,
- topLevelTypes.topSelectionChange
- ]
- }
-};
-
-var activeElement = null;
-var activeElementID = null;
-var lastSelection = null;
-var mouseDown = false;
-
-/**
- * Get an object which is a unique representation of the current selection.
- *
- * The return value will not be consistent across nodes or browsers, but
- * two identical selections on the same node will return identical objects.
- *
- * @param {DOMElement} node
- * @param {object}
- */
-function getSelection(node) {
- if ('selectionStart' in node &&
- ReactInputSelection.hasSelectionCapabilities(node)) {
- return {
- start: node.selectionStart,
- end: node.selectionEnd
- };
- } else if (document.selection) {
- var range = document.selection.createRange();
- return {
- parentElement: range.parentElement(),
- text: range.text,
- top: range.boundingTop,
- left: range.boundingLeft
- };
- } else {
- var selection = window.getSelection();
- return {
- anchorNode: selection.anchorNode,
- anchorOffset: selection.anchorOffset,
- focusNode: selection.focusNode,
- focusOffset: selection.focusOffset
- };
- }
-}
-
-/**
- * Poll selection to see whether it's changed.
- *
- * @param {object} nativeEvent
- * @return {?SyntheticEvent}
- */
-function constructSelectEvent(nativeEvent) {
- // Ensure we have the right element, and that the user is not dragging a
- // selection (this matches native `select` event behavior). In HTML5, select
- // fires only on input and textarea thus if there's no focused element we
- // won't dispatch.
- if (mouseDown ||
- activeElement == null ||
- activeElement != getActiveElement()) {
- return;
- }
-
- // Only fire when selection has actually changed.
- var currentSelection = getSelection(activeElement);
- if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
- lastSelection = currentSelection;
-
- var syntheticEvent = SyntheticEvent.getPooled(
- eventTypes.select,
- activeElementID,
- nativeEvent
- );
-
- syntheticEvent.type = 'select';
- syntheticEvent.target = activeElement;
-
- EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent);
-
- return syntheticEvent;
- }
-}
-
-/**
- * This plugin creates an `onSelect` event that normalizes select events
- * across form elements.
- *
- * Supported elements are:
- * - input (see `isTextInputElement`)
- * - textarea
- * - contentEditable
- *
- * This differs from native browser implementations in the following ways:
- * - Fires on contentEditable fields as well as inputs.
- * - Fires for collapsed selection.
- * - Fires after user input.
- */
-var SelectEventPlugin = {
-
- eventTypes: eventTypes,
-
- /**
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {DOMEventTarget} topLevelTarget The listening component root node.
- * @param {string} topLevelTargetID ID of `topLevelTarget`.
- * @param {object} nativeEvent Native browser event.
- * @return {*} An accumulation of synthetic events.
- * @see {EventPluginHub.extractEvents}
- */
- extractEvents: function(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent) {
-
- switch (topLevelType) {
- // Track the input node that has focus.
- case topLevelTypes.topFocus:
- if (isTextInputElement(topLevelTarget) ||
- topLevelTarget.contentEditable === 'true') {
- activeElement = topLevelTarget;
- activeElementID = topLevelTargetID;
- lastSelection = null;
- }
- break;
- case topLevelTypes.topBlur:
- activeElement = null;
- activeElementID = null;
- lastSelection = null;
- break;
-
- // Don't fire the event while the user is dragging. This matches the
- // semantics of the native select event.
- case topLevelTypes.topMouseDown:
- mouseDown = true;
- break;
- case topLevelTypes.topContextMenu:
- case topLevelTypes.topMouseUp:
- mouseDown = false;
- return constructSelectEvent(nativeEvent);
-
- // Chrome and IE fire non-standard event when selection is changed (and
- // sometimes when it hasn't).
- // Firefox doesn't support selectionchange, so check selection status
- // after each key entry. The selection changes after keydown and before
- // keyup, but we check on keydown as well in the case of holding down a
- // key, when multiple keydown events are fired but only one keyup is.
- case topLevelTypes.topSelectionChange:
- case topLevelTypes.topKeyDown:
- case topLevelTypes.topKeyUp:
- return constructSelectEvent(nativeEvent);
- }
- }
-};
-
-module.exports = SelectEventPlugin;
-
-},{"./EventConstants":15,"./EventPropagators":20,"./ReactInputSelection":58,"./SyntheticEvent":84,"./getActiveElement":108,"./isTextInputElement":123,"./keyOf":127,"./shallowEqual":139}],79:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ServerReactRootIndex
- * @typechecks
- */
-
-"use strict";
-
-/**
- * Size of the reactRoot ID space. We generate random numbers for React root
- * IDs and if there's a collision the events and DOM update system will
- * get confused. In the future we need a way to generate GUIDs but for
- * now this will work on a smaller scale.
- */
-var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53);
-
-var ServerReactRootIndex = {
- createReactRootIndex: function() {
- return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX);
- }
-};
-
-module.exports = ServerReactRootIndex;
-
-},{}],80:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SimpleEventPlugin
- */
-
-"use strict";
-
-var EventConstants = _dereq_("./EventConstants");
-var EventPluginUtils = _dereq_("./EventPluginUtils");
-var EventPropagators = _dereq_("./EventPropagators");
-var SyntheticClipboardEvent = _dereq_("./SyntheticClipboardEvent");
-var SyntheticEvent = _dereq_("./SyntheticEvent");
-var SyntheticFocusEvent = _dereq_("./SyntheticFocusEvent");
-var SyntheticKeyboardEvent = _dereq_("./SyntheticKeyboardEvent");
-var SyntheticMouseEvent = _dereq_("./SyntheticMouseEvent");
-var SyntheticDragEvent = _dereq_("./SyntheticDragEvent");
-var SyntheticTouchEvent = _dereq_("./SyntheticTouchEvent");
-var SyntheticUIEvent = _dereq_("./SyntheticUIEvent");
-var SyntheticWheelEvent = _dereq_("./SyntheticWheelEvent");
-
-var invariant = _dereq_("./invariant");
-var keyOf = _dereq_("./keyOf");
-
-var topLevelTypes = EventConstants.topLevelTypes;
-
-var eventTypes = {
- blur: {
- phasedRegistrationNames: {
- bubbled: keyOf({onBlur: true}),
- captured: keyOf({onBlurCapture: true})
- }
- },
- click: {
- phasedRegistrationNames: {
- bubbled: keyOf({onClick: true}),
- captured: keyOf({onClickCapture: true})
- }
- },
- contextMenu: {
- phasedRegistrationNames: {
- bubbled: keyOf({onContextMenu: true}),
- captured: keyOf({onContextMenuCapture: true})
- }
- },
- copy: {
- phasedRegistrationNames: {
- bubbled: keyOf({onCopy: true}),
- captured: keyOf({onCopyCapture: true})
- }
- },
- cut: {
- phasedRegistrationNames: {
- bubbled: keyOf({onCut: true}),
- captured: keyOf({onCutCapture: true})
- }
- },
- doubleClick: {
- phasedRegistrationNames: {
- bubbled: keyOf({onDoubleClick: true}),
- captured: keyOf({onDoubleClickCapture: true})
- }
- },
- drag: {
- phasedRegistrationNames: {
- bubbled: keyOf({onDrag: true}),
- captured: keyOf({onDragCapture: true})
- }
- },
- dragEnd: {
- phasedRegistrationNames: {
- bubbled: keyOf({onDragEnd: true}),
- captured: keyOf({onDragEndCapture: true})
- }
- },
- dragEnter: {
- phasedRegistrationNames: {
- bubbled: keyOf({onDragEnter: true}),
- captured: keyOf({onDragEnterCapture: true})
- }
- },
- dragExit: {
- phasedRegistrationNames: {
- bubbled: keyOf({onDragExit: true}),
- captured: keyOf({onDragExitCapture: true})
- }
- },
- dragLeave: {
- phasedRegistrationNames: {
- bubbled: keyOf({onDragLeave: true}),
- captured: keyOf({onDragLeaveCapture: true})
- }
- },
- dragOver: {
- phasedRegistrationNames: {
- bubbled: keyOf({onDragOver: true}),
- captured: keyOf({onDragOverCapture: true})
- }
- },
- dragStart: {
- phasedRegistrationNames: {
- bubbled: keyOf({onDragStart: true}),
- captured: keyOf({onDragStartCapture: true})
- }
- },
- drop: {
- phasedRegistrationNames: {
- bubbled: keyOf({onDrop: true}),
- captured: keyOf({onDropCapture: true})
- }
- },
- focus: {
- phasedRegistrationNames: {
- bubbled: keyOf({onFocus: true}),
- captured: keyOf({onFocusCapture: true})
- }
- },
- input: {
- phasedRegistrationNames: {
- bubbled: keyOf({onInput: true}),
- captured: keyOf({onInputCapture: true})
- }
- },
- keyDown: {
- phasedRegistrationNames: {
- bubbled: keyOf({onKeyDown: true}),
- captured: keyOf({onKeyDownCapture: true})
- }
- },
- keyPress: {
- phasedRegistrationNames: {
- bubbled: keyOf({onKeyPress: true}),
- captured: keyOf({onKeyPressCapture: true})
- }
- },
- keyUp: {
- phasedRegistrationNames: {
- bubbled: keyOf({onKeyUp: true}),
- captured: keyOf({onKeyUpCapture: true})
- }
- },
- load: {
- phasedRegistrationNames: {
- bubbled: keyOf({onLoad: true}),
- captured: keyOf({onLoadCapture: true})
- }
- },
- error: {
- phasedRegistrationNames: {
- bubbled: keyOf({onError: true}),
- captured: keyOf({onErrorCapture: true})
- }
- },
- // Note: We do not allow listening to mouseOver events. Instead, use the
- // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`.
- mouseDown: {
- phasedRegistrationNames: {
- bubbled: keyOf({onMouseDown: true}),
- captured: keyOf({onMouseDownCapture: true})
- }
- },
- mouseMove: {
- phasedRegistrationNames: {
- bubbled: keyOf({onMouseMove: true}),
- captured: keyOf({onMouseMoveCapture: true})
- }
- },
- mouseOut: {
- phasedRegistrationNames: {
- bubbled: keyOf({onMouseOut: true}),
- captured: keyOf({onMouseOutCapture: true})
- }
- },
- mouseOver: {
- phasedRegistrationNames: {
- bubbled: keyOf({onMouseOver: true}),
- captured: keyOf({onMouseOverCapture: true})
- }
- },
- mouseUp: {
- phasedRegistrationNames: {
- bubbled: keyOf({onMouseUp: true}),
- captured: keyOf({onMouseUpCapture: true})
- }
- },
- paste: {
- phasedRegistrationNames: {
- bubbled: keyOf({onPaste: true}),
- captured: keyOf({onPasteCapture: true})
- }
- },
- reset: {
- phasedRegistrationNames: {
- bubbled: keyOf({onReset: true}),
- captured: keyOf({onResetCapture: true})
- }
- },
- scroll: {
- phasedRegistrationNames: {
- bubbled: keyOf({onScroll: true}),
- captured: keyOf({onScrollCapture: true})
- }
- },
- submit: {
- phasedRegistrationNames: {
- bubbled: keyOf({onSubmit: true}),
- captured: keyOf({onSubmitCapture: true})
- }
- },
- touchCancel: {
- phasedRegistrationNames: {
- bubbled: keyOf({onTouchCancel: true}),
- captured: keyOf({onTouchCancelCapture: true})
- }
- },
- touchEnd: {
- phasedRegistrationNames: {
- bubbled: keyOf({onTouchEnd: true}),
- captured: keyOf({onTouchEndCapture: true})
- }
- },
- touchMove: {
- phasedRegistrationNames: {
- bubbled: keyOf({onTouchMove: true}),
- captured: keyOf({onTouchMoveCapture: true})
- }
- },
- touchStart: {
- phasedRegistrationNames: {
- bubbled: keyOf({onTouchStart: true}),
- captured: keyOf({onTouchStartCapture: true})
- }
- },
- wheel: {
- phasedRegistrationNames: {
- bubbled: keyOf({onWheel: true}),
- captured: keyOf({onWheelCapture: true})
- }
- }
-};
-
-var topLevelEventsToDispatchConfig = {
- topBlur: eventTypes.blur,
- topClick: eventTypes.click,
- topContextMenu: eventTypes.contextMenu,
- topCopy: eventTypes.copy,
- topCut: eventTypes.cut,
- topDoubleClick: eventTypes.doubleClick,
- topDrag: eventTypes.drag,
- topDragEnd: eventTypes.dragEnd,
- topDragEnter: eventTypes.dragEnter,
- topDragExit: eventTypes.dragExit,
- topDragLeave: eventTypes.dragLeave,
- topDragOver: eventTypes.dragOver,
- topDragStart: eventTypes.dragStart,
- topDrop: eventTypes.drop,
- topError: eventTypes.error,
- topFocus: eventTypes.focus,
- topInput: eventTypes.input,
- topKeyDown: eventTypes.keyDown,
- topKeyPress: eventTypes.keyPress,
- topKeyUp: eventTypes.keyUp,
- topLoad: eventTypes.load,
- topMouseDown: eventTypes.mouseDown,
- topMouseMove: eventTypes.mouseMove,
- topMouseOut: eventTypes.mouseOut,
- topMouseOver: eventTypes.mouseOver,
- topMouseUp: eventTypes.mouseUp,
- topPaste: eventTypes.paste,
- topReset: eventTypes.reset,
- topScroll: eventTypes.scroll,
- topSubmit: eventTypes.submit,
- topTouchCancel: eventTypes.touchCancel,
- topTouchEnd: eventTypes.touchEnd,
- topTouchMove: eventTypes.touchMove,
- topTouchStart: eventTypes.touchStart,
- topWheel: eventTypes.wheel
-};
-
-for (var topLevelType in topLevelEventsToDispatchConfig) {
- topLevelEventsToDispatchConfig[topLevelType].dependencies = [topLevelType];
-}
-
-var SimpleEventPlugin = {
-
- eventTypes: eventTypes,
-
- /**
- * Same as the default implementation, except cancels the event when return
- * value is false.
- *
- * @param {object} Event to be dispatched.
- * @param {function} Application-level callback.
- * @param {string} domID DOM ID to pass to the callback.
- */
- executeDispatch: function(event, listener, domID) {
- var returnValue = EventPluginUtils.executeDispatch(event, listener, domID);
- if (returnValue === false) {
- event.stopPropagation();
- event.preventDefault();
- }
- },
-
- /**
- * @param {string} topLevelType Record from `EventConstants`.
- * @param {DOMEventTarget} topLevelTarget The listening component root node.
- * @param {string} topLevelTargetID ID of `topLevelTarget`.
- * @param {object} nativeEvent Native browser event.
- * @return {*} An accumulation of synthetic events.
- * @see {EventPluginHub.extractEvents}
- */
- extractEvents: function(
- topLevelType,
- topLevelTarget,
- topLevelTargetID,
- nativeEvent) {
- var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
- if (!dispatchConfig) {
- return null;
- }
- var EventConstructor;
- switch (topLevelType) {
- case topLevelTypes.topInput:
- case topLevelTypes.topLoad:
- case topLevelTypes.topError:
- case topLevelTypes.topReset:
- case topLevelTypes.topSubmit:
- // HTML Events
- // @see http://www.w3.org/TR/html5/index.html#events-0
- EventConstructor = SyntheticEvent;
- break;
- case topLevelTypes.topKeyPress:
- // FireFox creates a keypress event for function keys too. This removes
- // the unwanted keypress events.
- if (nativeEvent.charCode === 0) {
- return null;
- }
- /* falls through */
- case topLevelTypes.topKeyDown:
- case topLevelTypes.topKeyUp:
- EventConstructor = SyntheticKeyboardEvent;
- break;
- case topLevelTypes.topBlur:
- case topLevelTypes.topFocus:
- EventConstructor = SyntheticFocusEvent;
- break;
- case topLevelTypes.topClick:
- // Firefox creates a click event on right mouse clicks. This removes the
- // unwanted click events.
- if (nativeEvent.button === 2) {
- return null;
- }
- /* falls through */
- case topLevelTypes.topContextMenu:
- case topLevelTypes.topDoubleClick:
- case topLevelTypes.topMouseDown:
- case topLevelTypes.topMouseMove:
- case topLevelTypes.topMouseOut:
- case topLevelTypes.topMouseOver:
- case topLevelTypes.topMouseUp:
- EventConstructor = SyntheticMouseEvent;
- break;
- case topLevelTypes.topDrag:
- case topLevelTypes.topDragEnd:
- case topLevelTypes.topDragEnter:
- case topLevelTypes.topDragExit:
- case topLevelTypes.topDragLeave:
- case topLevelTypes.topDragOver:
- case topLevelTypes.topDragStart:
- case topLevelTypes.topDrop:
- EventConstructor = SyntheticDragEvent;
- break;
- case topLevelTypes.topTouchCancel:
- case topLevelTypes.topTouchEnd:
- case topLevelTypes.topTouchMove:
- case topLevelTypes.topTouchStart:
- EventConstructor = SyntheticTouchEvent;
- break;
- case topLevelTypes.topScroll:
- EventConstructor = SyntheticUIEvent;
- break;
- case topLevelTypes.topWheel:
- EventConstructor = SyntheticWheelEvent;
- break;
- case topLevelTypes.topCopy:
- case topLevelTypes.topCut:
- case topLevelTypes.topPaste:
- EventConstructor = SyntheticClipboardEvent;
- break;
- }
- ("production" !== "development" ? invariant(
- EventConstructor,
- 'SimpleEventPlugin: Unhandled event type, `%s`.',
- topLevelType
- ) : invariant(EventConstructor));
- var event = EventConstructor.getPooled(
- dispatchConfig,
- topLevelTargetID,
- nativeEvent
- );
- EventPropagators.accumulateTwoPhaseDispatches(event);
- return event;
- }
-
-};
-
-module.exports = SimpleEventPlugin;
-
-},{"./EventConstants":15,"./EventPluginUtils":19,"./EventPropagators":20,"./SyntheticClipboardEvent":81,"./SyntheticDragEvent":83,"./SyntheticEvent":84,"./SyntheticFocusEvent":85,"./SyntheticKeyboardEvent":87,"./SyntheticMouseEvent":88,"./SyntheticTouchEvent":89,"./SyntheticUIEvent":90,"./SyntheticWheelEvent":91,"./invariant":120,"./keyOf":127}],81:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticClipboardEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var SyntheticEvent = _dereq_("./SyntheticEvent");
-
-/**
- * @interface Event
- * @see http://www.w3.org/TR/clipboard-apis/
- */
-var ClipboardEventInterface = {
- clipboardData: function(event) {
- return (
- 'clipboardData' in event ?
- event.clipboardData :
- window.clipboardData
- );
- }
-};
-
-/**
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- * @extends {SyntheticUIEvent}
- */
-function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent) {
- SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
-}
-
-SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface);
-
-module.exports = SyntheticClipboardEvent;
-
-
-},{"./SyntheticEvent":84}],82:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticCompositionEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var SyntheticEvent = _dereq_("./SyntheticEvent");
-
-/**
- * @interface Event
- * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
- */
-var CompositionEventInterface = {
- data: null
-};
-
-/**
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- * @extends {SyntheticUIEvent}
- */
-function SyntheticCompositionEvent(
- dispatchConfig,
- dispatchMarker,
- nativeEvent) {
- SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
-}
-
-SyntheticEvent.augmentClass(
- SyntheticCompositionEvent,
- CompositionEventInterface
-);
-
-module.exports = SyntheticCompositionEvent;
-
-
-},{"./SyntheticEvent":84}],83:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticDragEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var SyntheticMouseEvent = _dereq_("./SyntheticMouseEvent");
-
-/**
- * @interface DragEvent
- * @see http://www.w3.org/TR/DOM-Level-3-Events/
- */
-var DragEventInterface = {
- dataTransfer: null
-};
-
-/**
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- * @extends {SyntheticUIEvent}
- */
-function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent) {
- SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
-}
-
-SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface);
-
-module.exports = SyntheticDragEvent;
-
-},{"./SyntheticMouseEvent":88}],84:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var PooledClass = _dereq_("./PooledClass");
-
-var emptyFunction = _dereq_("./emptyFunction");
-var getEventTarget = _dereq_("./getEventTarget");
-var merge = _dereq_("./merge");
-var mergeInto = _dereq_("./mergeInto");
-
-/**
- * @interface Event
- * @see http://www.w3.org/TR/DOM-Level-3-Events/
- */
-var EventInterface = {
- type: null,
- target: getEventTarget,
- // currentTarget is set when dispatching; no use in copying it here
- currentTarget: emptyFunction.thatReturnsNull,
- eventPhase: null,
- bubbles: null,
- cancelable: null,
- timeStamp: function(event) {
- return event.timeStamp || Date.now();
- },
- defaultPrevented: null,
- isTrusted: null
-};
-
-/**
- * Synthetic events are dispatched by event plugins, typically in response to a
- * top-level event delegation handler.
- *
- * These systems should generally use pooling to reduce the frequency of garbage
- * collection. The system should check `isPersistent` to determine whether the
- * event should be released into the pool after being dispatched. Users that
- * need a persisted event should invoke `persist`.
- *
- * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
- * normalizing browser quirks. Subclasses do not necessarily have to implement a
- * DOM interface; custom application-specific events can also subclass this.
- *
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- */
-function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) {
- this.dispatchConfig = dispatchConfig;
- this.dispatchMarker = dispatchMarker;
- this.nativeEvent = nativeEvent;
-
- var Interface = this.constructor.Interface;
- for (var propName in Interface) {
- if (!Interface.hasOwnProperty(propName)) {
- continue;
- }
- var normalize = Interface[propName];
- if (normalize) {
- this[propName] = normalize(nativeEvent);
- } else {
- this[propName] = nativeEvent[propName];
- }
- }
-
- var defaultPrevented = nativeEvent.defaultPrevented != null ?
- nativeEvent.defaultPrevented :
- nativeEvent.returnValue === false;
- if (defaultPrevented) {
- this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
- } else {
- this.isDefaultPrevented = emptyFunction.thatReturnsFalse;
- }
- this.isPropagationStopped = emptyFunction.thatReturnsFalse;
-}
-
-mergeInto(SyntheticEvent.prototype, {
-
- preventDefault: function() {
- this.defaultPrevented = true;
- var event = this.nativeEvent;
- event.preventDefault ? event.preventDefault() : event.returnValue = false;
- this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
- },
-
- stopPropagation: function() {
- var event = this.nativeEvent;
- event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;
- this.isPropagationStopped = emptyFunction.thatReturnsTrue;
- },
-
- /**
- * We release all dispatched `SyntheticEvent`s after each event loop, adding
- * them back into the pool. This allows a way to hold onto a reference that
- * won't be added back into the pool.
- */
- persist: function() {
- this.isPersistent = emptyFunction.thatReturnsTrue;
- },
-
- /**
- * Checks if this event should be released back into the pool.
- *
- * @return {boolean} True if this should not be released, false otherwise.
- */
- isPersistent: emptyFunction.thatReturnsFalse,
-
- /**
- * `PooledClass` looks for `destructor` on each instance it releases.
- */
- destructor: function() {
- var Interface = this.constructor.Interface;
- for (var propName in Interface) {
- this[propName] = null;
- }
- this.dispatchConfig = null;
- this.dispatchMarker = null;
- this.nativeEvent = null;
- }
-
-});
-
-SyntheticEvent.Interface = EventInterface;
-
-/**
- * Helper to reduce boilerplate when creating subclasses.
- *
- * @param {function} Class
- * @param {?object} Interface
- */
-SyntheticEvent.augmentClass = function(Class, Interface) {
- var Super = this;
-
- var prototype = Object.create(Super.prototype);
- mergeInto(prototype, Class.prototype);
- Class.prototype = prototype;
- Class.prototype.constructor = Class;
-
- Class.Interface = merge(Super.Interface, Interface);
- Class.augmentClass = Super.augmentClass;
-
- PooledClass.addPoolingTo(Class, PooledClass.threeArgumentPooler);
-};
-
-PooledClass.addPoolingTo(SyntheticEvent, PooledClass.threeArgumentPooler);
-
-module.exports = SyntheticEvent;
-
-},{"./PooledClass":26,"./emptyFunction":102,"./getEventTarget":111,"./merge":130,"./mergeInto":132}],85:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticFocusEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var SyntheticUIEvent = _dereq_("./SyntheticUIEvent");
-
-/**
- * @interface FocusEvent
- * @see http://www.w3.org/TR/DOM-Level-3-Events/
- */
-var FocusEventInterface = {
- relatedTarget: null
-};
-
-/**
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- * @extends {SyntheticUIEvent}
- */
-function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent) {
- SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
-}
-
-SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface);
-
-module.exports = SyntheticFocusEvent;
-
-},{"./SyntheticUIEvent":90}],86:[function(_dereq_,module,exports){
-/**
- * Copyright 2013 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticInputEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var SyntheticEvent = _dereq_("./SyntheticEvent");
-
-/**
- * @interface Event
- * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
- * /#events-inputevents
- */
-var InputEventInterface = {
- data: null
-};
-
-/**
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- * @extends {SyntheticUIEvent}
- */
-function SyntheticInputEvent(
- dispatchConfig,
- dispatchMarker,
- nativeEvent) {
- SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
-}
-
-SyntheticEvent.augmentClass(
- SyntheticInputEvent,
- InputEventInterface
-);
-
-module.exports = SyntheticInputEvent;
-
-
-},{"./SyntheticEvent":84}],87:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticKeyboardEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var SyntheticUIEvent = _dereq_("./SyntheticUIEvent");
-
-var getEventKey = _dereq_("./getEventKey");
-var getEventModifierState = _dereq_("./getEventModifierState");
-
-/**
- * @interface KeyboardEvent
- * @see http://www.w3.org/TR/DOM-Level-3-Events/
- */
-var KeyboardEventInterface = {
- key: getEventKey,
- location: null,
- ctrlKey: null,
- shiftKey: null,
- altKey: null,
- metaKey: null,
- repeat: null,
- locale: null,
- getModifierState: getEventModifierState,
- // Legacy Interface
- charCode: function(event) {
- // `charCode` is the result of a KeyPress event and represents the value of
- // the actual printable character.
-
- // KeyPress is deprecated but its replacement is not yet final and not
- // implemented in any major browser.
- if (event.type === 'keypress') {
- // IE8 does not implement "charCode", but "keyCode" has the correct value.
- return 'charCode' in event ? event.charCode : event.keyCode;
- }
- return 0;
- },
- keyCode: function(event) {
- // `keyCode` is the result of a KeyDown/Up event and represents the value of
- // physical keyboard key.
-
- // The actual meaning of the value depends on the users' keyboard layout
- // which cannot be detected. Assuming that it is a US keyboard layout
- // provides a surprisingly accurate mapping for US and European users.
- // Due to this, it is left to the user to implement at this time.
- if (event.type === 'keydown' || event.type === 'keyup') {
- return event.keyCode;
- }
- return 0;
- },
- which: function(event) {
- // `which` is an alias for either `keyCode` or `charCode` depending on the
- // type of the event. There is no need to determine the type of the event
- // as `keyCode` and `charCode` are either aliased or default to zero.
- return event.keyCode || event.charCode;
- }
-};
-
-/**
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- * @extends {SyntheticUIEvent}
- */
-function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent) {
- SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
-}
-
-SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface);
-
-module.exports = SyntheticKeyboardEvent;
-
-},{"./SyntheticUIEvent":90,"./getEventKey":109,"./getEventModifierState":110}],88:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticMouseEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var SyntheticUIEvent = _dereq_("./SyntheticUIEvent");
-var ViewportMetrics = _dereq_("./ViewportMetrics");
-
-var getEventModifierState = _dereq_("./getEventModifierState");
-
-/**
- * @interface MouseEvent
- * @see http://www.w3.org/TR/DOM-Level-3-Events/
- */
-var MouseEventInterface = {
- screenX: null,
- screenY: null,
- clientX: null,
- clientY: null,
- ctrlKey: null,
- shiftKey: null,
- altKey: null,
- metaKey: null,
- getModifierState: getEventModifierState,
- button: function(event) {
- // Webkit, Firefox, IE9+
- // which: 1 2 3
- // button: 0 1 2 (standard)
- var button = event.button;
- if ('which' in event) {
- return button;
- }
- // IE<9
- // which: undefined
- // button: 0 0 0
- // button: 1 4 2 (onmouseup)
- return button === 2 ? 2 : button === 4 ? 1 : 0;
- },
- buttons: null,
- relatedTarget: function(event) {
- return event.relatedTarget || (
- event.fromElement === event.srcElement ?
- event.toElement :
- event.fromElement
- );
- },
- // "Proprietary" Interface.
- pageX: function(event) {
- return 'pageX' in event ?
- event.pageX :
- event.clientX + ViewportMetrics.currentScrollLeft;
- },
- pageY: function(event) {
- return 'pageY' in event ?
- event.pageY :
- event.clientY + ViewportMetrics.currentScrollTop;
- }
-};
-
-/**
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- * @extends {SyntheticUIEvent}
- */
-function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent) {
- SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
-}
-
-SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);
-
-module.exports = SyntheticMouseEvent;
-
-},{"./SyntheticUIEvent":90,"./ViewportMetrics":93,"./getEventModifierState":110}],89:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticTouchEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var SyntheticUIEvent = _dereq_("./SyntheticUIEvent");
-
-var getEventModifierState = _dereq_("./getEventModifierState");
-
-/**
- * @interface TouchEvent
- * @see http://www.w3.org/TR/touch-events/
- */
-var TouchEventInterface = {
- touches: null,
- targetTouches: null,
- changedTouches: null,
- altKey: null,
- metaKey: null,
- ctrlKey: null,
- shiftKey: null,
- getModifierState: getEventModifierState
-};
-
-/**
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- * @extends {SyntheticUIEvent}
- */
-function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent) {
- SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
-}
-
-SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface);
-
-module.exports = SyntheticTouchEvent;
-
-},{"./SyntheticUIEvent":90,"./getEventModifierState":110}],90:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticUIEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var SyntheticEvent = _dereq_("./SyntheticEvent");
-
-var getEventTarget = _dereq_("./getEventTarget");
-
-/**
- * @interface UIEvent
- * @see http://www.w3.org/TR/DOM-Level-3-Events/
- */
-var UIEventInterface = {
- view: function(event) {
- if (event.view) {
- return event.view;
- }
-
- var target = getEventTarget(event);
- if (target != null && target.window === target) {
- // target is a window object
- return target;
- }
-
- var doc = target.ownerDocument;
- // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
- if (doc) {
- return doc.defaultView || doc.parentWindow;
- } else {
- return window;
- }
- },
- detail: function(event) {
- return event.detail || 0;
- }
-};
-
-/**
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- * @extends {SyntheticEvent}
- */
-function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent) {
- SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
-}
-
-SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface);
-
-module.exports = SyntheticUIEvent;
-
-},{"./SyntheticEvent":84,"./getEventTarget":111}],91:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule SyntheticWheelEvent
- * @typechecks static-only
- */
-
-"use strict";
-
-var SyntheticMouseEvent = _dereq_("./SyntheticMouseEvent");
-
-/**
- * @interface WheelEvent
- * @see http://www.w3.org/TR/DOM-Level-3-Events/
- */
-var WheelEventInterface = {
- deltaX: function(event) {
- return (
- 'deltaX' in event ? event.deltaX :
- // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
- 'wheelDeltaX' in event ? -event.wheelDeltaX : 0
- );
- },
- deltaY: function(event) {
- return (
- 'deltaY' in event ? event.deltaY :
- // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
- 'wheelDeltaY' in event ? -event.wheelDeltaY :
- // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
- 'wheelDelta' in event ? -event.wheelDelta : 0
- );
- },
- deltaZ: null,
-
- // Browsers without "deltaMode" is reporting in raw wheel delta where one
- // notch on the scroll is always +/- 120, roughly equivalent to pixels.
- // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
- // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
- deltaMode: null
-};
-
-/**
- * @param {object} dispatchConfig Configuration used to dispatch this event.
- * @param {string} dispatchMarker Marker identifying the event target.
- * @param {object} nativeEvent Native browser event.
- * @extends {SyntheticMouseEvent}
- */
-function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent) {
- SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
-}
-
-SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface);
-
-module.exports = SyntheticWheelEvent;
-
-},{"./SyntheticMouseEvent":88}],92:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule Transaction
- */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-
-/**
- * `Transaction` creates a black box that is able to wrap any method such that
- * certain invariants are maintained before and after the method is invoked
- * (Even if an exception is thrown while invoking the wrapped method). Whoever
- * instantiates a transaction can provide enforcers of the invariants at
- * creation time. The `Transaction` class itself will supply one additional
- * automatic invariant for you - the invariant that any transaction instance
- * should not be run while it is already being run. You would typically create a
- * single instance of a `Transaction` for reuse multiple times, that potentially
- * is used to wrap several different methods. Wrappers are extremely simple -
- * they only require implementing two methods.
- *
- * <pre>
- * wrappers (injected at creation time)
- * + +
- * | |
- * +-----------------|--------|--------------+
- * | v | |
- * | +---------------+ | |
- * | +--| wrapper1 |---|----+ |
- * | | +---------------+ v | |
- * | | +-------------+ | |
- * | | +----| wrapper2 |--------+ |
- * | | | +-------------+ | | |
- * | | | | | |
- * | v v v v | wrapper
- * | +---+ +---+ +---------+ +---+ +---+ | invariants
- * perform(anyMethod) | | | | | | | | | | | | maintained
- * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
- * | | | | | | | | | | | |
- * | | | | | | | | | | | |
- * | | | | | | | | | | | |
- * | +---+ +---+ +---------+ +---+ +---+ |
- * | initialize close |
- * +-----------------------------------------+
- * </pre>
- *
- * Use cases:
- * - Preserving the input selection ranges before/after reconciliation.
- * Restoring selection even in the event of an unexpected error.
- * - Deactivating events while rearranging the DOM, preventing blurs/focuses,
- * while guaranteeing that afterwards, the event system is reactivated.
- * - Flushing a queue of collected DOM mutations to the main UI thread after a
- * reconciliation takes place in a worker thread.
- * - Invoking any collected `componentDidUpdate` callbacks after rendering new
- * content.
- * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue
- * to preserve the `scrollTop` (an automatic scroll aware DOM).
- * - (Future use case): Layout calculations before and after DOM upates.
- *
- * Transactional plugin API:
- * - A module that has an `initialize` method that returns any precomputation.
- * - and a `close` method that accepts the precomputation. `close` is invoked
- * when the wrapped process is completed, or has failed.
- *
- * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules
- * that implement `initialize` and `close`.
- * @return {Transaction} Single transaction for reuse in thread.
- *
- * @class Transaction
- */
-var Mixin = {
- /**
- * Sets up this instance so that it is prepared for collecting metrics. Does
- * so such that this setup method may be used on an instance that is already
- * initialized, in a way that does not consume additional memory upon reuse.
- * That can be useful if you decide to make your subclass of this mixin a
- * "PooledClass".
- */
- reinitializeTransaction: function() {
- this.transactionWrappers = this.getTransactionWrappers();
- if (!this.wrapperInitData) {
- this.wrapperInitData = [];
- } else {
- this.wrapperInitData.length = 0;
- }
- this._isInTransaction = false;
- },
-
- _isInTransaction: false,
-
- /**
- * @abstract
- * @return {Array<TransactionWrapper>} Array of transaction wrappers.
- */
- getTransactionWrappers: null,
-
- isInTransaction: function() {
- return !!this._isInTransaction;
- },
-
- /**
- * Executes the function within a safety window. Use this for the top level
- * methods that result in large amounts of computation/mutations that would
- * need to be safety checked.
- *
- * @param {function} method Member of scope to call.
- * @param {Object} scope Scope to invoke from.
- * @param {Object?=} args... Arguments to pass to the method (optional).
- * Helps prevent need to bind in many cases.
- * @return Return value from `method`.
- */
- perform: function(method, scope, a, b, c, d, e, f) {
- ("production" !== "development" ? invariant(
- !this.isInTransaction(),
- 'Transaction.perform(...): Cannot initialize a transaction when there ' +
- 'is already an outstanding transaction.'
- ) : invariant(!this.isInTransaction()));
- var errorThrown;
- var ret;
- try {
- this._isInTransaction = true;
- // Catching errors makes debugging more difficult, so we start with
- // errorThrown set to true before setting it to false after calling
- // close -- if it's still set to true in the finally block, it means
- // one of these calls threw.
- errorThrown = true;
- this.initializeAll(0);
- ret = method.call(scope, a, b, c, d, e, f);
- errorThrown = false;
- } finally {
- try {
- if (errorThrown) {
- // If `method` throws, prefer to show that stack trace over any thrown
- // by invoking `closeAll`.
- try {
- this.closeAll(0);
- } catch (err) {
- }
- } else {
- // Since `method` didn't throw, we don't want to silence the exception
- // here.
- this.closeAll(0);
- }
- } finally {
- this._isInTransaction = false;
- }
- }
- return ret;
- },
-
- initializeAll: function(startIndex) {
- var transactionWrappers = this.transactionWrappers;
- for (var i = startIndex; i < transactionWrappers.length; i++) {
- var wrapper = transactionWrappers[i];
- try {
- // Catching errors makes debugging more difficult, so we start with the
- // OBSERVED_ERROR state before overwriting it with the real return value
- // of initialize -- if it's still set to OBSERVED_ERROR in the finally
- // block, it means wrapper.initialize threw.
- this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
- this.wrapperInitData[i] = wrapper.initialize ?
- wrapper.initialize.call(this) :
- null;
- } finally {
- if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) {
- // The initializer for wrapper i threw an error; initialize the
- // remaining wrappers but silence any exceptions from them to ensure
- // that the first error is the one to bubble up.
- try {
- this.initializeAll(i + 1);
- } catch (err) {
- }
- }
- }
- }
- },
-
- /**
- * Invokes each of `this.transactionWrappers.close[i]` functions, passing into
- * them the respective return values of `this.transactionWrappers.init[i]`
- * (`close`rs that correspond to initializers that failed will not be
- * invoked).
- */
- closeAll: function(startIndex) {
- ("production" !== "development" ? invariant(
- this.isInTransaction(),
- 'Transaction.closeAll(): Cannot close transaction when none are open.'
- ) : invariant(this.isInTransaction()));
- var transactionWrappers = this.transactionWrappers;
- for (var i = startIndex; i < transactionWrappers.length; i++) {
- var wrapper = transactionWrappers[i];
- var initData = this.wrapperInitData[i];
- var errorThrown;
- try {
- // Catching errors makes debugging more difficult, so we start with
- // errorThrown set to true before setting it to false after calling
- // close -- if it's still set to true in the finally block, it means
- // wrapper.close threw.
- errorThrown = true;
- if (initData !== Transaction.OBSERVED_ERROR) {
- wrapper.close && wrapper.close.call(this, initData);
- }
- errorThrown = false;
- } finally {
- if (errorThrown) {
- // The closer for wrapper i threw an error; close the remaining
- // wrappers but silence any exceptions from them to ensure that the
- // first error is the one to bubble up.
- try {
- this.closeAll(i + 1);
- } catch (e) {
- }
- }
- }
- }
- this.wrapperInitData.length = 0;
- }
-};
-
-var Transaction = {
-
- Mixin: Mixin,
-
- /**
- * Token to look for to determine if an error occured.
- */
- OBSERVED_ERROR: {}
-
-};
-
-module.exports = Transaction;
-
-},{"./invariant":120}],93:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule ViewportMetrics
- */
-
-"use strict";
-
-var getUnboundedScrollPosition = _dereq_("./getUnboundedScrollPosition");
-
-var ViewportMetrics = {
-
- currentScrollLeft: 0,
-
- currentScrollTop: 0,
-
- refreshScrollValues: function() {
- var scrollPosition = getUnboundedScrollPosition(window);
- ViewportMetrics.currentScrollLeft = scrollPosition.x;
- ViewportMetrics.currentScrollTop = scrollPosition.y;
- }
-
-};
-
-module.exports = ViewportMetrics;
-
-},{"./getUnboundedScrollPosition":116}],94:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule accumulate
- */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Accumulates items that must not be null or undefined.
- *
- * This is used to conserve memory by avoiding array allocations.
- *
- * @return {*|array<*>} An accumulation of items.
- */
-function accumulate(current, next) {
- ("production" !== "development" ? invariant(
- next != null,
- 'accumulate(...): Accumulated items must be not be null or undefined.'
- ) : invariant(next != null));
- if (current == null) {
- return next;
- } else {
- // Both are not empty. Warning: Never call x.concat(y) when you are not
- // certain that x is an Array (x could be a string with concat method).
- var currentIsArray = Array.isArray(current);
- var nextIsArray = Array.isArray(next);
- if (currentIsArray) {
- return current.concat(next);
- } else {
- if (nextIsArray) {
- return [current].concat(next);
- } else {
- return [current, next];
- }
- }
- }
-}
-
-module.exports = accumulate;
-
-},{"./invariant":120}],95:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule adler32
- */
-
-/* jslint bitwise:true */
-
-"use strict";
-
-var MOD = 65521;
-
-// This is a clean-room implementation of adler32 designed for detecting
-// if markup is not what we expect it to be. It does not need to be
-// cryptographically strong, only reasonable good at detecting if markup
-// generated on the server is different than that on the client.
-function adler32(data) {
- var a = 1;
- var b = 0;
- for (var i = 0; i < data.length; i++) {
- a = (a + data.charCodeAt(i)) % MOD;
- b = (b + a) % MOD;
- }
- return a | (b << 16);
-}
-
-module.exports = adler32;
-
-},{}],96:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule containsNode
- * @typechecks
- */
-
-var isTextNode = _dereq_("./isTextNode");
-
-/*jslint bitwise:true */
-
-/**
- * Checks if a given DOM node contains or is another DOM node.
- *
- * @param {?DOMNode} outerNode Outer DOM node.
- * @param {?DOMNode} innerNode Inner DOM node.
- * @return {boolean} True if `outerNode` contains or is `innerNode`.
- */
-function containsNode(outerNode, innerNode) {
- if (!outerNode || !innerNode) {
- return false;
- } else if (outerNode === innerNode) {
- return true;
- } else if (isTextNode(outerNode)) {
- return false;
- } else if (isTextNode(innerNode)) {
- return containsNode(outerNode, innerNode.parentNode);
- } else if (outerNode.contains) {
- return outerNode.contains(innerNode);
- } else if (outerNode.compareDocumentPosition) {
- return !!(outerNode.compareDocumentPosition(innerNode) & 16);
- } else {
- return false;
- }
-}
-
-module.exports = containsNode;
-
-},{"./isTextNode":124}],97:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule copyProperties
- */
-
-/**
- * Copy properties from one or more objects (up to 5) into the first object.
- * This is a shallow copy. It mutates the first object and also returns it.
- *
- * NOTE: `arguments` has a very significant performance penalty, which is why
- * we don't support unlimited arguments.
- */
-function copyProperties(obj, a, b, c, d, e, f) {
- obj = obj || {};
-
- if ("production" !== "development") {
- if (f) {
- throw new Error('Too many arguments passed to copyProperties');
- }
- }
-
- var args = [a, b, c, d, e];
- var ii = 0, v;
- while (args[ii]) {
- v = args[ii++];
- for (var k in v) {
- obj[k] = v[k];
- }
-
- // IE ignores toString in object iteration.. See:
- // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html
- if (v.hasOwnProperty && v.hasOwnProperty('toString') &&
- (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) {
- obj.toString = v.toString;
- }
- }
-
- return obj;
-}
-
-module.exports = copyProperties;
-
-},{}],98:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule createArrayFrom
- * @typechecks
- */
-
-var toArray = _dereq_("./toArray");
-
-/**
- * Perform a heuristic test to determine if an object is "array-like".
- *
- * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
- * Joshu replied: "Mu."
- *
- * This function determines if its argument has "array nature": it returns
- * true if the argument is an actual array, an `arguments' object, or an
- * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
- *
- * It will return false for other array-like objects like Filelist.
- *
- * @param {*} obj
- * @return {boolean}
- */
-function hasArrayNature(obj) {
- return (
- // not null/false
- !!obj &&
- // arrays are objects, NodeLists are functions in Safari
- (typeof obj == 'object' || typeof obj == 'function') &&
- // quacks like an array
- ('length' in obj) &&
- // not window
- !('setInterval' in obj) &&
- // no DOM node should be considered an array-like
- // a 'select' element has 'length' and 'item' properties on IE8
- (typeof obj.nodeType != 'number') &&
- (
- // a real array
- (// HTMLCollection/NodeList
- (Array.isArray(obj) ||
- // arguments
- ('callee' in obj) || 'item' in obj))
- )
- );
-}
-
-/**
- * Ensure that the argument is an array by wrapping it in an array if it is not.
- * Creates a copy of the argument if it is already an array.
- *
- * This is mostly useful idiomatically:
- *
- * var createArrayFrom = require('createArrayFrom');
- *
- * function takesOneOrMoreThings(things) {
- * things = createArrayFrom(things);
- * ...
- * }
- *
- * This allows you to treat `things' as an array, but accept scalars in the API.
- *
- * If you need to convert an array-like object, like `arguments`, into an array
- * use toArray instead.
- *
- * @param {*} obj
- * @return {array}
- */
-function createArrayFrom(obj) {
- if (!hasArrayNature(obj)) {
- return [obj];
- } else if (Array.isArray(obj)) {
- return obj.slice();
- } else {
- return toArray(obj);
- }
-}
-
-module.exports = createArrayFrom;
-
-},{"./toArray":141}],99:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule createFullPageComponent
- * @typechecks
- */
-
-"use strict";
-
-// Defeat circular references by requiring this directly.
-var ReactCompositeComponent = _dereq_("./ReactCompositeComponent");
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Create a component that will throw an exception when unmounted.
- *
- * Components like <html> <head> and <body> can't be removed or added
- * easily in a cross-browser way, however it's valuable to be able to
- * take advantage of React's reconciliation for styling and <title>
- * management. So we just document it and throw in dangerous cases.
- *
- * @param {function} componentClass convenience constructor to wrap
- * @return {function} convenience constructor of new component
- */
-function createFullPageComponent(componentClass) {
- var FullPageComponent = ReactCompositeComponent.createClass({
- displayName: 'ReactFullPageComponent' + (
- componentClass.type.displayName || ''
- ),
-
- componentWillUnmount: function() {
- ("production" !== "development" ? invariant(
- false,
- '%s tried to unmount. Because of cross-browser quirks it is ' +
- 'impossible to unmount some top-level components (eg <html>, <head>, ' +
- 'and <body>) reliably and efficiently. To fix this, have a single ' +
- 'top-level component that never unmounts render these elements.',
- this.constructor.displayName
- ) : invariant(false));
- },
-
- render: function() {
- return this.transferPropsTo(componentClass(null, this.props.children));
- }
- });
-
- return FullPageComponent;
-}
-
-module.exports = createFullPageComponent;
-
-},{"./ReactCompositeComponent":33,"./invariant":120}],100:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule createNodesFromMarkup
- * @typechecks
- */
-
-/*jslint evil: true, sub: true */
-
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-
-var createArrayFrom = _dereq_("./createArrayFrom");
-var getMarkupWrap = _dereq_("./getMarkupWrap");
-var invariant = _dereq_("./invariant");
-
-/**
- * Dummy container used to render all markup.
- */
-var dummyNode =
- ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
-
-/**
- * Pattern used by `getNodeName`.
- */
-var nodeNamePattern = /^\s*<(\w+)/;
-
-/**
- * Extracts the `nodeName` of the first element in a string of markup.
- *
- * @param {string} markup String of markup.
- * @return {?string} Node name of the supplied markup.
- */
-function getNodeName(markup) {
- var nodeNameMatch = markup.match(nodeNamePattern);
- return nodeNameMatch && nodeNameMatch[1].toLowerCase();
-}
-
-/**
- * Creates an array containing the nodes rendered from the supplied markup. The
- * optionally supplied `handleScript` function will be invoked once for each
- * <script> element that is rendered. If no `handleScript` function is supplied,
- * an exception is thrown if any <script> elements are rendered.
- *
- * @param {string} markup A string of valid HTML markup.
- * @param {?function} handleScript Invoked once for each rendered <script>.
- * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes.
- */
-function createNodesFromMarkup(markup, handleScript) {
- var node = dummyNode;
- ("production" !== "development" ? invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized') : invariant(!!dummyNode));
- var nodeName = getNodeName(markup);
-
- var wrap = nodeName && getMarkupWrap(nodeName);
- if (wrap) {
- node.innerHTML = wrap[1] + markup + wrap[2];
-
- var wrapDepth = wrap[0];
- while (wrapDepth--) {
- node = node.lastChild;
- }
- } else {
- node.innerHTML = markup;
- }
-
- var scripts = node.getElementsByTagName('script');
- if (scripts.length) {
- ("production" !== "development" ? invariant(
- handleScript,
- 'createNodesFromMarkup(...): Unexpected <script> element rendered.'
- ) : invariant(handleScript));
- createArrayFrom(scripts).forEach(handleScript);
- }
-
- var nodes = createArrayFrom(node.childNodes);
- while (node.lastChild) {
- node.removeChild(node.lastChild);
- }
- return nodes;
-}
-
-module.exports = createNodesFromMarkup;
-
-},{"./ExecutionEnvironment":21,"./createArrayFrom":98,"./getMarkupWrap":112,"./invariant":120}],101:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule dangerousStyleValue
- * @typechecks static-only
- */
-
-"use strict";
-
-var CSSProperty = _dereq_("./CSSProperty");
-
-var isUnitlessNumber = CSSProperty.isUnitlessNumber;
-
-/**
- * Convert a value into the proper css writable value. The style name `name`
- * should be logical (no hyphens), as specified
- * in `CSSProperty.isUnitlessNumber`.
- *
- * @param {string} name CSS property name such as `topMargin`.
- * @param {*} value CSS property value such as `10px`.
- * @return {string} Normalized style value with dimensions applied.
- */
-function dangerousStyleValue(name, value) {
- // Note that we've removed escapeTextForBrowser() calls here since the
- // whole string will be escaped when the attribute is injected into
- // the markup. If you provide unsafe user data here they can inject
- // arbitrary CSS which may be problematic (I couldn't repro this):
- // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
- // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
- // This is not an XSS hole but instead a potential CSS injection issue
- // which has lead to a greater discussion about how we're going to
- // trust URLs moving forward. See #2115901
-
- var isEmpty = value == null || typeof value === 'boolean' || value === '';
- if (isEmpty) {
- return '';
- }
-
- var isNonNumeric = isNaN(value);
- if (isNonNumeric || value === 0 ||
- isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) {
- return '' + value; // cast to string
- }
-
- if (typeof value === 'string') {
- value = value.trim();
- }
- return value + 'px';
-}
-
-module.exports = dangerousStyleValue;
-
-},{"./CSSProperty":3}],102:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule emptyFunction
- */
-
-var copyProperties = _dereq_("./copyProperties");
-
-function makeEmptyFunction(arg) {
- return function() {
- return arg;
- };
-}
-
-/**
- * This function accepts and discards inputs; it has no side effects. This is
- * primarily useful idiomatically for overridable function endpoints which
- * always need to be callable, since JS lacks a null-call idiom ala Cocoa.
- */
-function emptyFunction() {}
-
-copyProperties(emptyFunction, {
- thatReturns: makeEmptyFunction,
- thatReturnsFalse: makeEmptyFunction(false),
- thatReturnsTrue: makeEmptyFunction(true),
- thatReturnsNull: makeEmptyFunction(null),
- thatReturnsThis: function() { return this; },
- thatReturnsArgument: function(arg) { return arg; }
-});
-
-module.exports = emptyFunction;
-
-},{"./copyProperties":97}],103:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule emptyObject
- */
-
-"use strict";
-
-var emptyObject = {};
-
-if ("production" !== "development") {
- Object.freeze(emptyObject);
-}
-
-module.exports = emptyObject;
-
-},{}],104:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule escapeTextForBrowser
- * @typechecks static-only
- */
-
-"use strict";
-
-var ESCAPE_LOOKUP = {
- "&": "&",
- ">": ">",
- "<": "<",
- "\"": """,
- "'": "'"
-};
-
-var ESCAPE_REGEX = /[&><"']/g;
-
-function escaper(match) {
- return ESCAPE_LOOKUP[match];
-}
-
-/**
- * Escapes text to prevent scripting attacks.
- *
- * @param {*} text Text value to escape.
- * @return {string} An escaped string.
- */
-function escapeTextForBrowser(text) {
- return ('' + text).replace(ESCAPE_REGEX, escaper);
-}
-
-module.exports = escapeTextForBrowser;
-
-},{}],105:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule flattenChildren
- */
-
-"use strict";
-
-var traverseAllChildren = _dereq_("./traverseAllChildren");
-var warning = _dereq_("./warning");
-
-/**
- * @param {function} traverseContext Context passed through traversal.
- * @param {?ReactComponent} child React child component.
- * @param {!string} name String name of key path to child.
- */
-function flattenSingleChildIntoContext(traverseContext, child, name) {
- // We found a component instance.
- var result = traverseContext;
- var keyUnique = !result.hasOwnProperty(name);
- ("production" !== "development" ? warning(
- keyUnique,
- 'flattenChildren(...): Encountered two children with the same key, ' +
- '`%s`. Child keys must be unique; when two children share a key, only ' +
- 'the first child will be used.',
- name
- ) : null);
- if (keyUnique && child != null) {
- result[name] = child;
- }
-}
-
-/**
- * Flattens children that are typically specified as `props.children`. Any null
- * children will not be included in the resulting object.
- * @return {!object} flattened children keyed by name.
- */
-function flattenChildren(children) {
- if (children == null) {
- return children;
- }
- var result = {};
- traverseAllChildren(children, flattenSingleChildIntoContext, result);
- return result;
-}
-
-module.exports = flattenChildren;
-
-},{"./traverseAllChildren":142,"./warning":143}],106:[function(_dereq_,module,exports){
-/**
- * Copyright 2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule focusNode
- */
-
-"use strict";
-
-/**
- * IE8 throws if an input/textarea is disabled and we try to focus it.
- * Focus only when necessary.
- *
- * @param {DOMElement} node input/textarea to focus
- */
-function focusNode(node) {
- if (!node.disabled) {
- node.focus();
- }
-}
-
-module.exports = focusNode;
-
-},{}],107:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule forEachAccumulated
- */
-
-"use strict";
-
-/**
- * @param {array} an "accumulation" of items which is either an Array or
- * a single item. Useful when paired with the `accumulate` module. This is a
- * simple utility that allows us to reason about a collection of items, but
- * handling the case when there is exactly one item (and we do not need to
- * allocate an array).
- */
-var forEachAccumulated = function(arr, cb, scope) {
- if (Array.isArray(arr)) {
- arr.forEach(cb, scope);
- } else if (arr) {
- cb.call(scope, arr);
- }
-};
-
-module.exports = forEachAccumulated;
-
-},{}],108:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule getActiveElement
- * @typechecks
- */
-
-/**
- * Same as document.activeElement but wraps in a try-catch block. In IE it is
- * not safe to call document.activeElement if there is nothing focused.
- *
- * The activeElement will be null only if the document body is not yet defined.
- */
-function getActiveElement() /*?DOMElement*/ {
- try {
- return document.activeElement || document.body;
- } catch (e) {
- return document.body;
- }
-}
-
-module.exports = getActiveElement;
-
-},{}],109:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule getEventKey
- * @typechecks static-only
- */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Normalization of deprecated HTML5 `key` values
- * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
- */
-var normalizeKey = {
- 'Esc': 'Escape',
- 'Spacebar': ' ',
- 'Left': 'ArrowLeft',
- 'Up': 'ArrowUp',
- 'Right': 'ArrowRight',
- 'Down': 'ArrowDown',
- 'Del': 'Delete',
- 'Win': 'OS',
- 'Menu': 'ContextMenu',
- 'Apps': 'ContextMenu',
- 'Scroll': 'ScrollLock',
- 'MozPrintableKey': 'Unidentified'
-};
-
-/**
- * Translation from legacy `which`/`keyCode` to HTML5 `key`
- * Only special keys supported, all others depend on keyboard layout or browser
- * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
- */
-var translateToKey = {
- 8: 'Backspace',
- 9: 'Tab',
- 12: 'Clear',
- 13: 'Enter',
- 16: 'Shift',
- 17: 'Control',
- 18: 'Alt',
- 19: 'Pause',
- 20: 'CapsLock',
- 27: 'Escape',
- 32: ' ',
- 33: 'PageUp',
- 34: 'PageDown',
- 35: 'End',
- 36: 'Home',
- 37: 'ArrowLeft',
- 38: 'ArrowUp',
- 39: 'ArrowRight',
- 40: 'ArrowDown',
- 45: 'Insert',
- 46: 'Delete',
- 112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6',
- 118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12',
- 144: 'NumLock',
- 145: 'ScrollLock',
- 224: 'Meta'
-};
-
-/**
- * @param {object} nativeEvent Native browser event.
- * @return {string} Normalized `key` property.
- */
-function getEventKey(nativeEvent) {
- if (nativeEvent.key) {
- // Normalize inconsistent values reported by browsers due to
- // implementations of a working draft specification.
-
- // FireFox implements `key` but returns `MozPrintableKey` for all
- // printable characters (normalized to `Unidentified`), ignore it.
- var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
- if (key !== 'Unidentified') {
- return key;
- }
- }
-
- // Browser does not implement `key`, polyfill as much of it as we can.
- if (nativeEvent.type === 'keypress') {
- // Create the character from the `charCode` ourselves and use as an almost
- // perfect replacement.
- var charCode = 'charCode' in nativeEvent ?
- nativeEvent.charCode :
- nativeEvent.keyCode;
-
- // The enter-key is technically both printable and non-printable and can
- // thus be captured by `keypress`, no other non-printable key should.
- return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
- }
- if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
- // While user keyboard layout determines the actual meaning of each
- // `keyCode` value, almost all function keys have a universal value.
- return translateToKey[nativeEvent.keyCode] || 'Unidentified';
- }
-
- ("production" !== "development" ? invariant(false, "Unexpected keyboard event type: %s", nativeEvent.type) : invariant(false));
-}
-
-module.exports = getEventKey;
-
-},{"./invariant":120}],110:[function(_dereq_,module,exports){
-/**
- * Copyright 2013 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule getEventModifierState
- * @typechecks static-only
- */
-
-"use strict";
-
-/**
- * Translation from modifier key to the associated property in the event.
- * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
- */
-
-var modifierKeyToProp = {
- 'Alt': 'altKey',
- 'Control': 'ctrlKey',
- 'Meta': 'metaKey',
- 'Shift': 'shiftKey'
-};
-
-// IE8 does not implement getModifierState so we simply map it to the only
-// modifier keys exposed by the event itself, does not support Lock-keys.
-// Currently, all major browsers except Chrome seems to support Lock-keys.
-function modifierStateGetter(keyArg) {
- /*jshint validthis:true */
- var syntheticEvent = this;
- var nativeEvent = syntheticEvent.nativeEvent;
- if (nativeEvent.getModifierState) {
- return nativeEvent.getModifierState(keyArg);
- }
- var keyProp = modifierKeyToProp[keyArg];
- return keyProp ? !!nativeEvent[keyProp] : false;
-}
-
-function getEventModifierState(nativeEvent) {
- return modifierStateGetter;
-}
-
-module.exports = getEventModifierState;
-
-},{}],111:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule getEventTarget
- * @typechecks static-only
- */
-
-"use strict";
-
-/**
- * Gets the target node from a native browser event by accounting for
- * inconsistencies in browser DOM APIs.
- *
- * @param {object} nativeEvent Native browser event.
- * @return {DOMEventTarget} Target node.
- */
-function getEventTarget(nativeEvent) {
- var target = nativeEvent.target || nativeEvent.srcElement || window;
- // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
- // @see http://www.quirksmode.org/js/events_properties.html
- return target.nodeType === 3 ? target.parentNode : target;
-}
-
-module.exports = getEventTarget;
-
-},{}],112:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule getMarkupWrap
- */
-
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Dummy container used to detect which wraps are necessary.
- */
-var dummyNode =
- ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
-
-/**
- * Some browsers cannot use `innerHTML` to render certain elements standalone,
- * so we wrap them, render the wrapped nodes, then extract the desired node.
- *
- * In IE8, certain elements cannot render alone, so wrap all elements ('*').
- */
-var shouldWrap = {
- // Force wrapping for SVG elements because if they get created inside a <div>,
- // they will be initialized in the wrong namespace (and will not display).
- 'circle': true,
- 'defs': true,
- 'ellipse': true,
- 'g': true,
- 'line': true,
- 'linearGradient': true,
- 'path': true,
- 'polygon': true,
- 'polyline': true,
- 'radialGradient': true,
- 'rect': true,
- 'stop': true,
- 'text': true
-};
-
-var selectWrap = [1, '<select multiple="true">', '</select>'];
-var tableWrap = [1, '<table>', '</table>'];
-var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
-
-var svgWrap = [1, '<svg>', '</svg>'];
-
-var markupWrap = {
- '*': [1, '?<div>', '</div>'],
-
- 'area': [1, '<map>', '</map>'],
- 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
- 'legend': [1, '<fieldset>', '</fieldset>'],
- 'param': [1, '<object>', '</object>'],
- 'tr': [2, '<table><tbody>', '</tbody></table>'],
-
- 'optgroup': selectWrap,
- 'option': selectWrap,
-
- 'caption': tableWrap,
- 'colgroup': tableWrap,
- 'tbody': tableWrap,
- 'tfoot': tableWrap,
- 'thead': tableWrap,
-
- 'td': trWrap,
- 'th': trWrap,
-
- 'circle': svgWrap,
- 'defs': svgWrap,
- 'ellipse': svgWrap,
- 'g': svgWrap,
- 'line': svgWrap,
- 'linearGradient': svgWrap,
- 'path': svgWrap,
- 'polygon': svgWrap,
- 'polyline': svgWrap,
- 'radialGradient': svgWrap,
- 'rect': svgWrap,
- 'stop': svgWrap,
- 'text': svgWrap
-};
-
-/**
- * Gets the markup wrap configuration for the supplied `nodeName`.
- *
- * NOTE: This lazily detects which wraps are necessary for the current browser.
- *
- * @param {string} nodeName Lowercase `nodeName`.
- * @return {?array} Markup wrap configuration, if applicable.
- */
-function getMarkupWrap(nodeName) {
- ("production" !== "development" ? invariant(!!dummyNode, 'Markup wrapping node not initialized') : invariant(!!dummyNode));
- if (!markupWrap.hasOwnProperty(nodeName)) {
- nodeName = '*';
- }
- if (!shouldWrap.hasOwnProperty(nodeName)) {
- if (nodeName === '*') {
- dummyNode.innerHTML = '<link />';
- } else {
- dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>';
- }
- shouldWrap[nodeName] = !dummyNode.firstChild;
- }
- return shouldWrap[nodeName] ? markupWrap[nodeName] : null;
-}
-
-
-module.exports = getMarkupWrap;
-
-},{"./ExecutionEnvironment":21,"./invariant":120}],113:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule getNodeForCharacterOffset
- */
-
-"use strict";
-
-/**
- * Given any node return the first leaf node without children.
- *
- * @param {DOMElement|DOMTextNode} node
- * @return {DOMElement|DOMTextNode}
- */
-function getLeafNode(node) {
- while (node && node.firstChild) {
- node = node.firstChild;
- }
- return node;
-}
-
-/**
- * Get the next sibling within a container. This will walk up the
- * DOM if a node's siblings have been exhausted.
- *
- * @param {DOMElement|DOMTextNode} node
- * @return {?DOMElement|DOMTextNode}
- */
-function getSiblingNode(node) {
- while (node) {
- if (node.nextSibling) {
- return node.nextSibling;
- }
- node = node.parentNode;
- }
-}
-
-/**
- * Get object describing the nodes which contain characters at offset.
- *
- * @param {DOMElement|DOMTextNode} root
- * @param {number} offset
- * @return {?object}
- */
-function getNodeForCharacterOffset(root, offset) {
- var node = getLeafNode(root);
- var nodeStart = 0;
- var nodeEnd = 0;
-
- while (node) {
- if (node.nodeType == 3) {
- nodeEnd = nodeStart + node.textContent.length;
-
- if (nodeStart <= offset && nodeEnd >= offset) {
- return {
- node: node,
- offset: offset - nodeStart
- };
- }
-
- nodeStart = nodeEnd;
- }
-
- node = getLeafNode(getSiblingNode(node));
- }
-}
-
-module.exports = getNodeForCharacterOffset;
-
-},{}],114:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule getReactRootElementInContainer
- */
-
-"use strict";
-
-var DOC_NODE_TYPE = 9;
-
-/**
- * @param {DOMElement|DOMDocument} container DOM element that may contain
- * a React component
- * @return {?*} DOM element that may have the reactRoot ID, or null.
- */
-function getReactRootElementInContainer(container) {
- if (!container) {
- return null;
- }
-
- if (container.nodeType === DOC_NODE_TYPE) {
- return container.documentElement;
- } else {
- return container.firstChild;
- }
-}
-
-module.exports = getReactRootElementInContainer;
-
-},{}],115:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule getTextContentAccessor
- */
-
-"use strict";
-
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-
-var contentKey = null;
-
-/**
- * Gets the key used to access text content on a DOM node.
- *
- * @return {?string} Key used to access text content.
- * @internal
- */
-function getTextContentAccessor() {
- if (!contentKey && ExecutionEnvironment.canUseDOM) {
- // Prefer textContent to innerText because many browsers support both but
- // SVG <text> elements don't support innerText even when <div> does.
- contentKey = 'textContent' in document.documentElement ?
- 'textContent' :
- 'innerText';
- }
- return contentKey;
-}
-
-module.exports = getTextContentAccessor;
-
-},{"./ExecutionEnvironment":21}],116:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule getUnboundedScrollPosition
- * @typechecks
- */
-
-"use strict";
-
-/**
- * Gets the scroll position of the supplied element or window.
- *
- * The return values are unbounded, unlike `getScrollPosition`. This means they
- * may be negative or exceed the element boundaries (which is possible using
- * inertial scrolling).
- *
- * @param {DOMWindow|DOMElement} scrollable
- * @return {object} Map with `x` and `y` keys.
- */
-function getUnboundedScrollPosition(scrollable) {
- if (scrollable === window) {
- return {
- x: window.pageXOffset || document.documentElement.scrollLeft,
- y: window.pageYOffset || document.documentElement.scrollTop
- };
- }
- return {
- x: scrollable.scrollLeft,
- y: scrollable.scrollTop
- };
-}
-
-module.exports = getUnboundedScrollPosition;
-
-},{}],117:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule hyphenate
- * @typechecks
- */
-
-var _uppercasePattern = /([A-Z])/g;
-
-/**
- * Hyphenates a camelcased string, for example:
- *
- * > hyphenate('backgroundColor')
- * < "background-color"
- *
- * For CSS style names, use `hyphenateStyleName` instead which works properly
- * with all vendor prefixes, including `ms`.
- *
- * @param {string} string
- * @return {string}
- */
-function hyphenate(string) {
- return string.replace(_uppercasePattern, '-$1').toLowerCase();
-}
-
-module.exports = hyphenate;
-
-},{}],118:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule hyphenateStyleName
- * @typechecks
- */
-
-"use strict";
-
-var hyphenate = _dereq_("./hyphenate");
-
-var msPattern = /^ms-/;
-
-/**
- * Hyphenates a camelcased CSS property name, for example:
- *
- * > hyphenate('backgroundColor')
- * < "background-color"
- * > hyphenate('MozTransition')
- * < "-moz-transition"
- * > hyphenate('msTransition')
- * < "-ms-transition"
- *
- * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
- * is converted to `-ms-`.
- *
- * @param {string} string
- * @return {string}
- */
-function hyphenateStyleName(string) {
- return hyphenate(string).replace(msPattern, '-ms-');
-}
-
-module.exports = hyphenateStyleName;
-
-},{"./hyphenate":117}],119:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule instantiateReactComponent
- * @typechecks static-only
- */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Validate a `componentDescriptor`. This should be exposed publicly in a follow
- * up diff.
- *
- * @param {object} descriptor
- * @return {boolean} Returns true if this is a valid descriptor of a Component.
- */
-function isValidComponentDescriptor(descriptor) {
- return (
- descriptor &&
- typeof descriptor.type === 'function' &&
- typeof descriptor.type.prototype.mountComponent === 'function' &&
- typeof descriptor.type.prototype.receiveComponent === 'function'
- );
-}
-
-/**
- * Given a `componentDescriptor` create an instance that will actually be
- * mounted. Currently it just extracts an existing clone from composite
- * components but this is an implementation detail which will change.
- *
- * @param {object} descriptor
- * @return {object} A new instance of componentDescriptor's constructor.
- * @protected
- */
-function instantiateReactComponent(descriptor) {
-
- // TODO: Make warning
- // if (__DEV__) {
- ("production" !== "development" ? invariant(
- isValidComponentDescriptor(descriptor),
- 'Only React Components are valid for mounting.'
- ) : invariant(isValidComponentDescriptor(descriptor)));
- // }
-
- return new descriptor.type(descriptor);
-}
-
-module.exports = instantiateReactComponent;
-
-},{"./invariant":120}],120:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule invariant
- */
-
-"use strict";
-
-/**
- * Use invariant() to assert state which your program assumes to be true.
- *
- * Provide sprintf-style format (only %s is supported) and arguments
- * to provide information about what broke and what you were
- * expecting.
- *
- * The invariant message will be stripped in production, but the invariant
- * will remain to ensure logic does not differ in production.
- */
-
-var invariant = function(condition, format, a, b, c, d, e, f) {
- if ("production" !== "development") {
- if (format === undefined) {
- throw new Error('invariant requires an error message argument');
- }
- }
-
- if (!condition) {
- var error;
- if (format === undefined) {
- error = new Error(
- 'Minified exception occurred; use the non-minified dev environment ' +
- 'for the full error message and additional helpful warnings.'
- );
- } else {
- var args = [a, b, c, d, e, f];
- var argIndex = 0;
- error = new Error(
- 'Invariant Violation: ' +
- format.replace(/%s/g, function() { return args[argIndex++]; })
- );
- }
-
- error.framesToPop = 1; // we don't care about invariant's own frame
- throw error;
- }
-};
-
-module.exports = invariant;
-
-},{}],121:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule isEventSupported
- */
-
-"use strict";
-
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-
-var useHasFeature;
-if (ExecutionEnvironment.canUseDOM) {
- useHasFeature =
- document.implementation &&
- document.implementation.hasFeature &&
- // always returns true in newer browsers as per the standard.
- // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
- document.implementation.hasFeature('', '') !== true;
-}
-
-/**
- * Checks if an event is supported in the current execution environment.
- *
- * NOTE: This will not work correctly for non-generic events such as `change`,
- * `reset`, `load`, `error`, and `select`.
- *
- * Borrows from Modernizr.
- *
- * @param {string} eventNameSuffix Event name, e.g. "click".
- * @param {?boolean} capture Check if the capture phase is supported.
- * @return {boolean} True if the event is supported.
- * @internal
- * @license Modernizr 3.0.0pre (Custom Build) | MIT
- */
-function isEventSupported(eventNameSuffix, capture) {
- if (!ExecutionEnvironment.canUseDOM ||
- capture && !('addEventListener' in document)) {
- return false;
- }
-
- var eventName = 'on' + eventNameSuffix;
- var isSupported = eventName in document;
-
- if (!isSupported) {
- var element = document.createElement('div');
- element.setAttribute(eventName, 'return;');
- isSupported = typeof element[eventName] === 'function';
- }
-
- if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {
- // This is the only way to test support for the `wheel` event in IE9+.
- isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
- }
-
- return isSupported;
-}
-
-module.exports = isEventSupported;
-
-},{"./ExecutionEnvironment":21}],122:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule isNode
- * @typechecks
- */
-
-/**
- * @param {*} object The object to check.
- * @return {boolean} Whether or not the object is a DOM node.
- */
-function isNode(object) {
- return !!(object && (
- typeof Node === 'function' ? object instanceof Node :
- typeof object === 'object' &&
- typeof object.nodeType === 'number' &&
- typeof object.nodeName === 'string'
- ));
-}
-
-module.exports = isNode;
-
-},{}],123:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule isTextInputElement
- */
-
-"use strict";
-
-/**
- * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
- */
-var supportedInputTypes = {
- 'color': true,
- 'date': true,
- 'datetime': true,
- 'datetime-local': true,
- 'email': true,
- 'month': true,
- 'number': true,
- 'password': true,
- 'range': true,
- 'search': true,
- 'tel': true,
- 'text': true,
- 'time': true,
- 'url': true,
- 'week': true
-};
-
-function isTextInputElement(elem) {
- return elem && (
- (elem.nodeName === 'INPUT' && supportedInputTypes[elem.type]) ||
- elem.nodeName === 'TEXTAREA'
- );
-}
-
-module.exports = isTextInputElement;
-
-},{}],124:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule isTextNode
- * @typechecks
- */
-
-var isNode = _dereq_("./isNode");
-
-/**
- * @param {*} object The object to check.
- * @return {boolean} Whether or not the object is a DOM text node.
- */
-function isTextNode(object) {
- return isNode(object) && object.nodeType == 3;
-}
-
-module.exports = isTextNode;
-
-},{"./isNode":122}],125:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule joinClasses
- * @typechecks static-only
- */
-
-"use strict";
-
-/**
- * Combines multiple className strings into one.
- * http://jsperf.com/joinclasses-args-vs-array
- *
- * @param {...?string} classes
- * @return {string}
- */
-function joinClasses(className/*, ... */) {
- if (!className) {
- className = '';
- }
- var nextClass;
- var argLength = arguments.length;
- if (argLength > 1) {
- for (var ii = 1; ii < argLength; ii++) {
- nextClass = arguments[ii];
- nextClass && (className += ' ' + nextClass);
- }
- }
- return className;
-}
-
-module.exports = joinClasses;
-
-},{}],126:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule keyMirror
- * @typechecks static-only
- */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Constructs an enumeration with keys equal to their value.
- *
- * For example:
- *
- * var COLORS = keyMirror({blue: null, red: null});
- * var myColor = COLORS.blue;
- * var isColorValid = !!COLORS[myColor];
- *
- * The last line could not be performed if the values of the generated enum were
- * not equal to their keys.
- *
- * Input: {key1: val1, key2: val2}
- * Output: {key1: key1, key2: key2}
- *
- * @param {object} obj
- * @return {object}
- */
-var keyMirror = function(obj) {
- var ret = {};
- var key;
- ("production" !== "development" ? invariant(
- obj instanceof Object && !Array.isArray(obj),
- 'keyMirror(...): Argument must be an object.'
- ) : invariant(obj instanceof Object && !Array.isArray(obj)));
- for (key in obj) {
- if (!obj.hasOwnProperty(key)) {
- continue;
- }
- ret[key] = key;
- }
- return ret;
-};
-
-module.exports = keyMirror;
-
-},{"./invariant":120}],127:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule keyOf
- */
-
-/**
- * Allows extraction of a minified key. Let's the build system minify keys
- * without loosing the ability to dynamically use key strings as values
- * themselves. Pass in an object with a single key/val pair and it will return
- * you the string key of that single record. Suppose you want to grab the
- * value for a key 'className' inside of an object. Key/val minification may
- * have aliased that key to be 'xa12'. keyOf({className: null}) will return
- * 'xa12' in that case. Resolve keys you want to use once at startup time, then
- * reuse those resolutions.
- */
-var keyOf = function(oneKeyObj) {
- var key;
- for (key in oneKeyObj) {
- if (!oneKeyObj.hasOwnProperty(key)) {
- continue;
- }
- return key;
- }
- return null;
-};
-
-
-module.exports = keyOf;
-
-},{}],128:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule mapObject
- */
-
-"use strict";
-
-/**
- * For each key/value pair, invokes callback func and constructs a resulting
- * object which contains, for every key in obj, values that are the result of
- * of invoking the function:
- *
- * func(value, key, iteration)
- *
- * Grepable names:
- *
- * function objectMap()
- * function objMap()
- *
- * @param {?object} obj Object to map keys over
- * @param {function} func Invoked for each key/val pair.
- * @param {?*} context
- * @return {?object} Result of mapping or null if obj is falsey
- */
-function mapObject(obj, func, context) {
- if (!obj) {
- return null;
- }
- var i = 0;
- var ret = {};
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- ret[key] = func.call(context, obj[key], key, i++);
- }
- }
- return ret;
-}
-
-module.exports = mapObject;
-
-},{}],129:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule memoizeStringOnly
- * @typechecks static-only
- */
-
-"use strict";
-
-/**
- * Memoizes the return value of a function that accepts one string argument.
- *
- * @param {function} callback
- * @return {function}
- */
-function memoizeStringOnly(callback) {
- var cache = {};
- return function(string) {
- if (cache.hasOwnProperty(string)) {
- return cache[string];
- } else {
- return cache[string] = callback.call(this, string);
- }
- };
-}
-
-module.exports = memoizeStringOnly;
-
-},{}],130:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule merge
- */
-
-"use strict";
-
-var mergeInto = _dereq_("./mergeInto");
-
-/**
- * Shallow merges two structures into a return value, without mutating either.
- *
- * @param {?object} one Optional object with properties to merge from.
- * @param {?object} two Optional object with properties to merge from.
- * @return {object} The shallow extension of one by two.
- */
-var merge = function(one, two) {
- var result = {};
- mergeInto(result, one);
- mergeInto(result, two);
- return result;
-};
-
-module.exports = merge;
-
-},{"./mergeInto":132}],131:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule mergeHelpers
- *
- * requiresPolyfills: Array.isArray
- */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-var keyMirror = _dereq_("./keyMirror");
-
-/**
- * Maximum number of levels to traverse. Will catch circular structures.
- * @const
- */
-var MAX_MERGE_DEPTH = 36;
-
-/**
- * We won't worry about edge cases like new String('x') or new Boolean(true).
- * Functions are considered terminals, and arrays are not.
- * @param {*} o The item/object/value to test.
- * @return {boolean} true iff the argument is a terminal.
- */
-var isTerminal = function(o) {
- return typeof o !== 'object' || o === null;
-};
-
-var mergeHelpers = {
-
- MAX_MERGE_DEPTH: MAX_MERGE_DEPTH,
-
- isTerminal: isTerminal,
-
- /**
- * Converts null/undefined values into empty object.
- *
- * @param {?Object=} arg Argument to be normalized (nullable optional)
- * @return {!Object}
- */
- normalizeMergeArg: function(arg) {
- return arg === undefined || arg === null ? {} : arg;
- },
-
- /**
- * If merging Arrays, a merge strategy *must* be supplied. If not, it is
- * likely the caller's fault. If this function is ever called with anything
- * but `one` and `two` being `Array`s, it is the fault of the merge utilities.
- *
- * @param {*} one Array to merge into.
- * @param {*} two Array to merge from.
- */
- checkMergeArrayArgs: function(one, two) {
- ("production" !== "development" ? invariant(
- Array.isArray(one) && Array.isArray(two),
- 'Tried to merge arrays, instead got %s and %s.',
- one,
- two
- ) : invariant(Array.isArray(one) && Array.isArray(two)));
- },
-
- /**
- * @param {*} one Object to merge into.
- * @param {*} two Object to merge from.
- */
- checkMergeObjectArgs: function(one, two) {
- mergeHelpers.checkMergeObjectArg(one);
- mergeHelpers.checkMergeObjectArg(two);
- },
-
- /**
- * @param {*} arg
- */
- checkMergeObjectArg: function(arg) {
- ("production" !== "development" ? invariant(
- !isTerminal(arg) && !Array.isArray(arg),
- 'Tried to merge an object, instead got %s.',
- arg
- ) : invariant(!isTerminal(arg) && !Array.isArray(arg)));
- },
-
- /**
- * @param {*} arg
- */
- checkMergeIntoObjectArg: function(arg) {
- ("production" !== "development" ? invariant(
- (!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg),
- 'Tried to merge into an object, instead got %s.',
- arg
- ) : invariant((!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg)));
- },
-
- /**
- * Checks that a merge was not given a circular object or an object that had
- * too great of depth.
- *
- * @param {number} Level of recursion to validate against maximum.
- */
- checkMergeLevel: function(level) {
- ("production" !== "development" ? invariant(
- level < MAX_MERGE_DEPTH,
- 'Maximum deep merge depth exceeded. You may be attempting to merge ' +
- 'circular structures in an unsupported way.'
- ) : invariant(level < MAX_MERGE_DEPTH));
- },
-
- /**
- * Checks that the supplied merge strategy is valid.
- *
- * @param {string} Array merge strategy.
- */
- checkArrayStrategy: function(strategy) {
- ("production" !== "development" ? invariant(
- strategy === undefined || strategy in mergeHelpers.ArrayStrategies,
- 'You must provide an array strategy to deep merge functions to ' +
- 'instruct the deep merge how to resolve merging two arrays.'
- ) : invariant(strategy === undefined || strategy in mergeHelpers.ArrayStrategies));
- },
-
- /**
- * Set of possible behaviors of merge algorithms when encountering two Arrays
- * that must be merged together.
- * - `clobber`: The left `Array` is ignored.
- * - `indexByIndex`: The result is achieved by recursively deep merging at
- * each index. (not yet supported.)
- */
- ArrayStrategies: keyMirror({
- Clobber: true,
- IndexByIndex: true
- })
-
-};
-
-module.exports = mergeHelpers;
-
-},{"./invariant":120,"./keyMirror":126}],132:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule mergeInto
- * @typechecks static-only
- */
-
-"use strict";
-
-var mergeHelpers = _dereq_("./mergeHelpers");
-
-var checkMergeObjectArg = mergeHelpers.checkMergeObjectArg;
-var checkMergeIntoObjectArg = mergeHelpers.checkMergeIntoObjectArg;
-
-/**
- * Shallow merges two structures by mutating the first parameter.
- *
- * @param {object|function} one Object to be merged into.
- * @param {?object} two Optional object with properties to merge from.
- */
-function mergeInto(one, two) {
- checkMergeIntoObjectArg(one);
- if (two != null) {
- checkMergeObjectArg(two);
- for (var key in two) {
- if (!two.hasOwnProperty(key)) {
- continue;
- }
- one[key] = two[key];
- }
- }
-}
-
-module.exports = mergeInto;
-
-},{"./mergeHelpers":131}],133:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule mixInto
- */
-
-"use strict";
-
-/**
- * Simply copies properties to the prototype.
- */
-var mixInto = function(constructor, methodBag) {
- var methodName;
- for (methodName in methodBag) {
- if (!methodBag.hasOwnProperty(methodName)) {
- continue;
- }
- constructor.prototype[methodName] = methodBag[methodName];
- }
-};
-
-module.exports = mixInto;
-
-},{}],134:[function(_dereq_,module,exports){
-/**
- * Copyright 2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule monitorCodeUse
- */
-
-"use strict";
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Provides open-source compatible instrumentation for monitoring certain API
- * uses before we're ready to issue a warning or refactor. It accepts an event
- * name which may only contain the characters [a-z0-9_] and an optional data
- * object with further information.
- */
-
-function monitorCodeUse(eventName, data) {
- ("production" !== "development" ? invariant(
- eventName && !/[^a-z0-9_]/.test(eventName),
- 'You must provide an eventName using only the characters [a-z0-9_]'
- ) : invariant(eventName && !/[^a-z0-9_]/.test(eventName)));
-}
-
-module.exports = monitorCodeUse;
-
-},{"./invariant":120}],135:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule onlyChild
- */
-"use strict";
-
-var ReactDescriptor = _dereq_("./ReactDescriptor");
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Returns the first child in a collection of children and verifies that there
- * is only one child in the collection. The current implementation of this
- * function assumes that a single child gets passed without a wrapper, but the
- * purpose of this helper function is to abstract away the particular structure
- * of children.
- *
- * @param {?object} children Child collection structure.
- * @return {ReactComponent} The first and only `ReactComponent` contained in the
- * structure.
- */
-function onlyChild(children) {
- ("production" !== "development" ? invariant(
- ReactDescriptor.isValidDescriptor(children),
- 'onlyChild must be passed a children with exactly one child.'
- ) : invariant(ReactDescriptor.isValidDescriptor(children)));
- return children;
-}
-
-module.exports = onlyChild;
-
-},{"./ReactDescriptor":51,"./invariant":120}],136:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule performance
- * @typechecks
- */
-
-"use strict";
-
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-
-var performance;
-
-if (ExecutionEnvironment.canUseDOM) {
- performance =
- window.performance ||
- window.msPerformance ||
- window.webkitPerformance;
-}
-
-module.exports = performance || {};
-
-},{"./ExecutionEnvironment":21}],137:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule performanceNow
- * @typechecks
- */
-
-var performance = _dereq_("./performance");
-
-/**
- * Detect if we can use `window.performance.now()` and gracefully fallback to
- * `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now
- * because of Facebook's testing infrastructure.
- */
-if (!performance || !performance.now) {
- performance = Date;
-}
-
-var performanceNow = performance.now.bind(performance);
-
-module.exports = performanceNow;
-
-},{"./performance":136}],138:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule setInnerHTML
- */
-
-"use strict";
-
-var ExecutionEnvironment = _dereq_("./ExecutionEnvironment");
-
-/**
- * Set the innerHTML property of a node, ensuring that whitespace is preserved
- * even in IE8.
- *
- * @param {DOMElement} node
- * @param {string} html
- * @internal
- */
-var setInnerHTML = function(node, html) {
- node.innerHTML = html;
-};
-
-if (ExecutionEnvironment.canUseDOM) {
- // IE8: When updating a just created node with innerHTML only leading
- // whitespace is removed. When updating an existing node with innerHTML
- // whitespace in root TextNodes is also collapsed.
- // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
-
- // Feature detection; only IE8 is known to behave improperly like this.
- var testElement = document.createElement('div');
- testElement.innerHTML = ' ';
- if (testElement.innerHTML === '') {
- setInnerHTML = function(node, html) {
- // Magic theory: IE8 supposedly differentiates between added and updated
- // nodes when processing innerHTML, innerHTML on updated nodes suffers
- // from worse whitespace behavior. Re-adding a node like this triggers
- // the initial and more favorable whitespace behavior.
- // TODO: What to do on a detached node?
- if (node.parentNode) {
- node.parentNode.replaceChild(node, node);
- }
-
- // We also implement a workaround for non-visible tags disappearing into
- // thin air on IE8, this only happens if there is no visible text
- // in-front of the non-visible tags. Piggyback on the whitespace fix
- // and simply check if any non-visible tags appear in the source.
- if (html.match(/^[ \r\n\t\f]/) ||
- html[0] === '<' && (
- html.indexOf('<noscript') !== -1 ||
- html.indexOf('<script') !== -1 ||
- html.indexOf('<style') !== -1 ||
- html.indexOf('<meta') !== -1 ||
- html.indexOf('<link') !== -1)) {
- // Recover leading whitespace by temporarily prepending any character.
- // \uFEFF has the potential advantage of being zero-width/invisible.
- node.innerHTML = '\uFEFF' + html;
-
- // deleteData leaves an empty `TextNode` which offsets the index of all
- // children. Definitely want to avoid this.
- var textNode = node.firstChild;
- if (textNode.data.length === 1) {
- node.removeChild(textNode);
- } else {
- textNode.deleteData(0, 1);
- }
- } else {
- node.innerHTML = html;
- }
- };
- }
-}
-
-module.exports = setInnerHTML;
-
-},{"./ExecutionEnvironment":21}],139:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule shallowEqual
- */
-
-"use strict";
-
-/**
- * Performs equality by iterating through keys on an object and returning
- * false when any key has values which are not strictly equal between
- * objA and objB. Returns true when the values of all keys are strictly equal.
- *
- * @return {boolean}
- */
-function shallowEqual(objA, objB) {
- if (objA === objB) {
- return true;
- }
- var key;
- // Test for A's keys different from B.
- for (key in objA) {
- if (objA.hasOwnProperty(key) &&
- (!objB.hasOwnProperty(key) || objA[key] !== objB[key])) {
- return false;
- }
- }
- // Test for B'a keys missing from A.
- for (key in objB) {
- if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) {
- return false;
- }
- }
- return true;
-}
-
-module.exports = shallowEqual;
-
-},{}],140:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule shouldUpdateReactComponent
- * @typechecks static-only
- */
-
-"use strict";
-
-/**
- * Given a `prevDescriptor` and `nextDescriptor`, determines if the existing
- * instance should be updated as opposed to being destroyed or replaced by a new
- * instance. Both arguments are descriptors. This ensures that this logic can
- * operate on stateless trees without any backing instance.
- *
- * @param {?object} prevDescriptor
- * @param {?object} nextDescriptor
- * @return {boolean} True if the existing instance should be updated.
- * @protected
- */
-function shouldUpdateReactComponent(prevDescriptor, nextDescriptor) {
- if (prevDescriptor && nextDescriptor &&
- prevDescriptor.type === nextDescriptor.type && (
- (prevDescriptor.props && prevDescriptor.props.key) ===
- (nextDescriptor.props && nextDescriptor.props.key)
- ) && prevDescriptor._owner === nextDescriptor._owner) {
- return true;
- }
- return false;
-}
-
-module.exports = shouldUpdateReactComponent;
-
-},{}],141:[function(_dereq_,module,exports){
-/**
- * Copyright 2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule toArray
- * @typechecks
- */
-
-var invariant = _dereq_("./invariant");
-
-/**
- * Convert array-like objects to arrays.
- *
- * This API assumes the caller knows the contents of the data type. For less
- * well defined inputs use createArrayFrom.
- *
- * @param {object|function|filelist} obj
- * @return {array}
- */
-function toArray(obj) {
- var length = obj.length;
-
- // Some browse builtin objects can report typeof 'function' (e.g. NodeList in
- // old versions of Safari).
- ("production" !== "development" ? invariant(
- !Array.isArray(obj) &&
- (typeof obj === 'object' || typeof obj === 'function'),
- 'toArray: Array-like object expected'
- ) : invariant(!Array.isArray(obj) &&
- (typeof obj === 'object' || typeof obj === 'function')));
-
- ("production" !== "development" ? invariant(
- typeof length === 'number',
- 'toArray: Object needs a length property'
- ) : invariant(typeof length === 'number'));
-
- ("production" !== "development" ? invariant(
- length === 0 ||
- (length - 1) in obj,
- 'toArray: Object should have keys for indices'
- ) : invariant(length === 0 ||
- (length - 1) in obj));
-
- // Old IE doesn't give collections access to hasOwnProperty. Assume inputs
- // without method will throw during the slice call and skip straight to the
- // fallback.
- if (obj.hasOwnProperty) {
- try {
- return Array.prototype.slice.call(obj);
- } catch (e) {
- // IE < 9 does not support Array#slice on collections objects
- }
- }
-
- // Fall back to copying key by key. This assumes all keys have a value,
- // so will not preserve sparsely populated inputs.
- var ret = Array(length);
- for (var ii = 0; ii < length; ii++) {
- ret[ii] = obj[ii];
- }
- return ret;
-}
-
-module.exports = toArray;
-
-},{"./invariant":120}],142:[function(_dereq_,module,exports){
-/**
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule traverseAllChildren
- */
-
-"use strict";
-
-var ReactInstanceHandles = _dereq_("./ReactInstanceHandles");
-var ReactTextComponent = _dereq_("./ReactTextComponent");
-
-var invariant = _dereq_("./invariant");
-
-var SEPARATOR = ReactInstanceHandles.SEPARATOR;
-var SUBSEPARATOR = ':';
-
-/**
- * TODO: Test that:
- * 1. `mapChildren` transforms strings and numbers into `ReactTextComponent`.
- * 2. it('should fail when supplied duplicate key', function() {
- * 3. That a single child and an array with one item have the same key pattern.
- * });
- */
-
-var userProvidedKeyEscaperLookup = {
- '=': '=0',
- '.': '=1',
- ':': '=2'
-};
-
-var userProvidedKeyEscapeRegex = /[=.:]/g;
-
-function userProvidedKeyEscaper(match) {
- return userProvidedKeyEscaperLookup[match];
-}
-
-/**
- * Generate a key string that identifies a component within a set.
- *
- * @param {*} component A component that could contain a manual key.
- * @param {number} index Index that is used if a manual key is not provided.
- * @return {string}
- */
-function getComponentKey(component, index) {
- if (component && component.props && component.props.key != null) {
- // Explicit key
- return wrapUserProvidedKey(component.props.key);
- }
- // Implicit key determined by the index in the set
- return index.toString(36);
-}
-
-/**
- * Escape a component key so that it is safe to use in a reactid.
- *
- * @param {*} key Component key to be escaped.
- * @return {string} An escaped string.
- */
-function escapeUserProvidedKey(text) {
- return ('' + text).replace(
- userProvidedKeyEscapeRegex,
- userProvidedKeyEscaper
- );
-}
-
-/**
- * Wrap a `key` value explicitly provided by the user to distinguish it from
- * implicitly-generated keys generated by a component's index in its parent.
- *
- * @param {string} key Value of a user-provided `key` attribute
- * @return {string}
- */
-function wrapUserProvidedKey(key) {
- return '$' + escapeUserProvidedKey(key);
-}
-
-/**
- * @param {?*} children Children tree container.
- * @param {!string} nameSoFar Name of the key path so far.
- * @param {!number} indexSoFar Number of children encountered until this point.
- * @param {!function} callback Callback to invoke with each child found.
- * @param {?*} traverseContext Used to pass information throughout the traversal
- * process.
- * @return {!number} The number of children in this subtree.
- */
-var traverseAllChildrenImpl =
- function(children, nameSoFar, indexSoFar, callback, traverseContext) {
- var subtreeCount = 0; // Count of children found in the current subtree.
- if (Array.isArray(children)) {
- for (var i = 0; i < children.length; i++) {
- var child = children[i];
- var nextName = (
- nameSoFar +
- (nameSoFar ? SUBSEPARATOR : SEPARATOR) +
- getComponentKey(child, i)
- );
- var nextIndex = indexSoFar + subtreeCount;
- subtreeCount += traverseAllChildrenImpl(
- child,
- nextName,
- nextIndex,
- callback,
- traverseContext
- );
- }
- } else {
- var type = typeof children;
- var isOnlyChild = nameSoFar === '';
- // If it's the only child, treat the name as if it was wrapped in an array
- // so that it's consistent if the number of children grows
- var storageName =
- isOnlyChild ? SEPARATOR + getComponentKey(children, 0) : nameSoFar;
- if (children == null || type === 'boolean') {
- // All of the above are perceived as null.
- callback(traverseContext, null, storageName, indexSoFar);
- subtreeCount = 1;
- } else if (children.type && children.type.prototype &&
- children.type.prototype.mountComponentIntoNode) {
- callback(traverseContext, children, storageName, indexSoFar);
- subtreeCount = 1;
- } else {
- if (type === 'object') {
- ("production" !== "development" ? invariant(
- !children || children.nodeType !== 1,
- 'traverseAllChildren(...): Encountered an invalid child; DOM ' +
- 'elements are not valid children of React components.'
- ) : invariant(!children || children.nodeType !== 1));
- for (var key in children) {
- if (children.hasOwnProperty(key)) {
- subtreeCount += traverseAllChildrenImpl(
- children[key],
- (
- nameSoFar + (nameSoFar ? SUBSEPARATOR : SEPARATOR) +
- wrapUserProvidedKey(key) + SUBSEPARATOR +
- getComponentKey(children[key], 0)
- ),
- indexSoFar + subtreeCount,
- callback,
- traverseContext
- );
- }
- }
- } else if (type === 'string') {
- var normalizedText = ReactTextComponent(children);
- callback(traverseContext, normalizedText, storageName, indexSoFar);
- subtreeCount += 1;
- } else if (type === 'number') {
- var normalizedNumber = ReactTextComponent('' + children);
- callback(traverseContext, normalizedNumber, storageName, indexSoFar);
- subtreeCount += 1;
- }
- }
- }
- return subtreeCount;
- };
-
-/**
- * Traverses children that are typically specified as `props.children`, but
- * might also be specified through attributes:
- *
- * - `traverseAllChildren(this.props.children, ...)`
- * - `traverseAllChildren(this.props.leftPanelChildren, ...)`
- *
- * The `traverseContext` is an optional argument that is passed through the
- * entire traversal. It can be used to store accumulations or anything else that
- * the callback might find relevant.
- *
- * @param {?*} children Children tree object.
- * @param {!function} callback To invoke upon traversing each child.
- * @param {?*} traverseContext Context for traversal.
- * @return {!number} The number of children in this subtree.
- */
-function traverseAllChildren(children, callback, traverseContext) {
- if (children == null) {
- return 0;
- }
-
- return traverseAllChildrenImpl(children, '', 0, callback, traverseContext);
-}
-
-module.exports = traverseAllChildren;
-
-},{"./ReactInstanceHandles":59,"./ReactTextComponent":75,"./invariant":120}],143:[function(_dereq_,module,exports){
-/**
- * Copyright 2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @providesModule warning
- */
-
-"use strict";
-
-var emptyFunction = _dereq_("./emptyFunction");
-
-/**
- * Similar to invariant but only logs a warning if the condition is not met.
- * This can be used to log issues in development environments in critical
- * paths. Removing the logging code for production environments will keep the
- * same logic and follow the same code paths.
- */
-
-var warning = emptyFunction;
-
-if ("production" !== "development") {
- warning = function(condition, format ) {var args=Array.prototype.slice.call(arguments,2);
- if (format === undefined) {
- throw new Error(
- '`warning(condition, format, ...args)` requires a warning ' +
- 'message argument'
- );
- }
-
- if (!condition) {
- var argIndex = 0;
- console.warn('Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];}));
- }
- };
-}
-
-module.exports = warning;
-
-},{"./emptyFunction":102}]},{},[27])
-(27)
-});
\ No newline at end of file
diff --git a/examples/todos/todos_appd/third_party/react-0.11.1.min.js b/examples/todos/todos_appd/third_party/react-0.11.1.min.js
deleted file mode 100644
index fee952a..0000000
--- a/examples/todos/todos_appd/third_party/react-0.11.1.min.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * React v0.11.1
- *
- * Copyright 2013-2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.React=e()}}(function(){return function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);throw new Error("Cannot find module '"+a+"'")}var c=n[a]={exports:{}};t[a][0].call(c.exports,function(e){var n=t[a][1][e];return o(n?n:e)},c,c.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a<r.length;a++)o(r[a]);return o}({1:[function(e,t){"use strict";var n=e("./focusNode"),r={componentDidMount:function(){this.props.autoFocus&&n(this.getDOMNode())}};t.exports=r},{"./focusNode":104}],2:[function(e,t){"use strict";function n(){var e=window.opera;return"object"==typeof e&&"function"==typeof e.version&&parseInt(e.version(),10)<=12}function r(e){return(e.ctrlKey||e.altKey||e.metaKey)&&!(e.ctrlKey&&e.altKey)}var o=e("./EventConstants"),i=e("./EventPropagators"),a=e("./ExecutionEnvironment"),s=e("./SyntheticInputEvent"),u=e("./keyOf"),c=a.canUseDOM&&"TextEvent"in window&&!("documentMode"in document||n()),l=32,p=String.fromCharCode(l),d=o.topLevelTypes,f={beforeInput:{phasedRegistrationNames:{bubbled:u({onBeforeInput:null}),captured:u({onBeforeInputCapture:null})},dependencies:[d.topCompositionEnd,d.topKeyPress,d.topTextInput,d.topPaste]}},h=null,v={eventTypes:f,extractEvents:function(e,t,n,o){var a;if(c)switch(e){case d.topKeyPress:var u=o.which;if(u!==l)return;a=String.fromCharCode(u);break;case d.topTextInput:if(a=o.data,a===p)return;break;default:return}else{switch(e){case d.topPaste:h=null;break;case d.topKeyPress:o.which&&!r(o)&&(h=String.fromCharCode(o.which));break;case d.topCompositionEnd:h=o.data}if(null===h)return;a=h}if(a){var v=s.getPooled(f.beforeInput,n,o);return v.data=a,h=null,i.accumulateTwoPhaseDispatches(v),v}}};t.exports=v},{"./EventConstants":15,"./EventPropagators":20,"./ExecutionEnvironment":21,"./SyntheticInputEvent":84,"./keyOf":125}],3:[function(e,t){"use strict";function n(e,t){return e+t.charAt(0).toUpperCase()+t.substring(1)}var r={columnCount:!0,fillOpacity:!0,flex:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},o=["Webkit","ms","Moz","O"];Object.keys(r).forEach(function(e){o.forEach(function(t){r[n(t,e)]=r[e]})});var i={background:{backgroundImage:!0,backgroundPosition:!0,backgroundRepeat:!0,backgroundColor:!0},border:{borderWidth:!0,borderStyle:!0,borderColor:!0},borderBottom:{borderBottomWidth:!0,borderBottomStyle:!0,borderBottomColor:!0},borderLeft:{borderLeftWidth:!0,borderLeftStyle:!0,borderLeftColor:!0},borderRight:{borderRightWidth:!0,borderRightStyle:!0,borderRightColor:!0},borderTop:{borderTopWidth:!0,borderTopStyle:!0,borderTopColor:!0},font:{fontStyle:!0,fontVariant:!0,fontWeight:!0,fontSize:!0,lineHeight:!0,fontFamily:!0}},a={isUnitlessNumber:r,shorthandPropertyExpansions:i};t.exports=a},{}],4:[function(e,t){"use strict";var n=e("./CSSProperty"),r=e("./dangerousStyleValue"),o=e("./hyphenateStyleName"),i=e("./memoizeStringOnly"),a=i(function(e){return o(e)}),s={createMarkupForStyles:function(e){var t="";for(var n in e)if(e.hasOwnProperty(n)){var o=e[n];null!=o&&(t+=a(n)+":",t+=r(n,o)+";")}return t||null},setValueForStyles:function(e,t){var o=e.style;for(var i in t)if(t.hasOwnProperty(i)){var a=r(i,t[i]);if(a)o[i]=a;else{var s=n.shorthandPropertyExpansions[i];if(s)for(var u in s)o[u]="";else o[i]=""}}}};t.exports=s},{"./CSSProperty":3,"./dangerousStyleValue":99,"./hyphenateStyleName":116,"./memoizeStringOnly":127}],5:[function(e,t){"use strict";function n(){this._callbacks=null,this._contexts=null}var r=e("./PooledClass"),o=e("./invariant"),i=e("./mixInto");i(n,{enqueue:function(e,t){this._callbacks=this._callbacks||[],this._contexts=this._contexts||[],this._callbacks.push(e),this._contexts.push(t)},notifyAll:function(){var e=this._callbacks,t=this._contexts;if(e){o(e.length===t.length),this._callbacks=null,this._contexts=null;for(var n=0,r=e.length;r>n;n++)e[n].call(t[n]);e.length=0,t.length=0}},reset:function(){this._callbacks=null,this._contexts=null},destructor:function(){this.reset()}}),r.addPoolingTo(n),t.exports=n},{"./PooledClass":26,"./invariant":118,"./mixInto":131}],6:[function(e,t){"use strict";function n(e){return"SELECT"===e.nodeName||"INPUT"===e.nodeName&&"file"===e.type}function r(e){var t=M.getPooled(P.change,_,e);C.accumulateTwoPhaseDispatches(t),R.batchedUpdates(o,t)}function o(e){y.enqueueEvents(e),y.processEventQueue()}function i(e,t){I=e,_=t,I.attachEvent("onchange",r)}function a(){I&&(I.detachEvent("onchange",r),I=null,_=null)}function s(e,t,n){return e===O.topChange?n:void 0}function u(e,t,n){e===O.topFocus?(a(),i(t,n)):e===O.topBlur&&a()}function c(e,t){I=e,_=t,T=e.value,N=Object.getOwnPropertyDescriptor(e.constructor.prototype,"value"),Object.defineProperty(I,"value",A),I.attachEvent("onpropertychange",p)}function l(){I&&(delete I.value,I.detachEvent("onpropertychange",p),I=null,_=null,T=null,N=null)}function p(e){if("value"===e.propertyName){var t=e.srcElement.value;t!==T&&(T=t,r(e))}}function d(e,t,n){return e===O.topInput?n:void 0}function f(e,t,n){e===O.topFocus?(l(),c(t,n)):e===O.topBlur&&l()}function h(e){return e!==O.topSelectionChange&&e!==O.topKeyUp&&e!==O.topKeyDown||!I||I.value===T?void 0:(T=I.value,_)}function v(e){return"INPUT"===e.nodeName&&("checkbox"===e.type||"radio"===e.type)}function m(e,t,n){return e===O.topClick?n:void 0}var g=e("./EventConstants"),y=e("./EventPluginHub"),C=e("./EventPropagators"),E=e("./ExecutionEnvironment"),R=e("./ReactUpdates"),M=e("./SyntheticEvent"),D=e("./isEventSupported"),x=e("./isTextInputElement"),b=e("./keyOf"),O=g.topLevelTypes,P={change:{phasedRegistrationNames:{bubbled:b({onChange:null}),captured:b({onChangeCapture:null})},dependencies:[O.topBlur,O.topChange,O.topClick,O.topFocus,O.topInput,O.topKeyDown,O.topKeyUp,O.topSelectionChange]}},I=null,_=null,T=null,N=null,w=!1;E.canUseDOM&&(w=D("change")&&(!("documentMode"in document)||document.documentMode>8));var S=!1;E.canUseDOM&&(S=D("input")&&(!("documentMode"in document)||document.documentMode>9));var A={get:function(){return N.get.call(this)},set:function(e){T=""+e,N.set.call(this,e)}},k={eventTypes:P,extractEvents:function(e,t,r,o){var i,a;if(n(t)?w?i=s:a=u:x(t)?S?i=d:(i=h,a=f):v(t)&&(i=m),i){var c=i(e,t,r);if(c){var l=M.getPooled(P.change,c,o);return C.accumulateTwoPhaseDispatches(l),l}}a&&a(e,t,r)}};t.exports=k},{"./EventConstants":15,"./EventPluginHub":17,"./EventPropagators":20,"./ExecutionEnvironment":21,"./ReactUpdates":74,"./SyntheticEvent":82,"./isEventSupported":119,"./isTextInputElement":121,"./keyOf":125}],7:[function(e,t){"use strict";var n=0,r={createReactRootIndex:function(){return n++}};t.exports=r},{}],8:[function(e,t){"use strict";function n(e){switch(e){case g.topCompositionStart:return C.compositionStart;case g.topCompositionEnd:return C.compositionEnd;case g.topCompositionUpdate:return C.compositionUpdate}}function r(e,t){return e===g.topKeyDown&&t.keyCode===h}function o(e,t){switch(e){case g.topKeyUp:return-1!==f.indexOf(t.keyCode);case g.topKeyDown:return t.keyCode!==h;case g.topKeyPress:case g.topMouseDown:case g.topBlur:return!0;default:return!1}}function i(e){this.root=e,this.startSelection=c.getSelection(e),this.startValue=this.getText()}var a=e("./EventConstants"),s=e("./EventPropagators"),u=e("./ExecutionEnvironment"),c=e("./ReactInputSelection"),l=e("./SyntheticCompositionEvent"),p=e("./getTextContentAccessor"),d=e("./keyOf"),f=[9,13,27,32],h=229,v=u.canUseDOM&&"CompositionEvent"in window,m=!v||"documentMode"in document&&document.documentMode>8&&document.documentMode<=11,g=a.topLevelTypes,y=null,C={compositionEnd:{phasedRegistrationNames:{bubbled:d({onCompositionEnd:null}),captured:d({onCompositionEndCapture:null})},dependencies:[g.topBlur,g.topCompositionEnd,g.topKeyDown,g.topKeyPress,g.topKeyUp,g.topMouseDown]},compositionStart:{phasedRegistrationNames:{bubbled:d({onCompositionStart:null}),captured:d({onCompositionStartCapture:null})},dependencies:[g.topBlur,g.topCompositionStart,g.topKeyDown,g.topKeyPress,g.topKeyUp,g.topMouseDown]},compositionUpdate:{phasedRegistrationNames:{bubbled:d({onCompositionUpdate:null}),captured:d({onCompositionUpdateCapture:null})},dependencies:[g.topBlur,g.topCompositionUpdate,g.topKeyDown,g.topKeyPress,g.topKeyUp,g.topMouseDown]}};i.prototype.getText=function(){return this.root.value||this.root[p()]},i.prototype.getData=function(){var e=this.getText(),t=this.startSelection.start,n=this.startValue.length-this.startSelection.end;return e.substr(t,e.length-n-t)};var E={eventTypes:C,extractEvents:function(e,t,a,u){var c,p;if(v?c=n(e):y?o(e,u)&&(c=C.compositionEnd):r(e,u)&&(c=C.compositionStart),m&&(y||c!==C.compositionStart?c===C.compositionEnd&&y&&(p=y.getData(),y=null):y=new i(t)),c){var d=l.getPooled(c,a,u);return p&&(d.data=p),s.accumulateTwoPhaseDispatches(d),d}}};t.exports=E},{"./EventConstants":15,"./EventPropagators":20,"./ExecutionEnvironment":21,"./ReactInputSelection":56,"./SyntheticCompositionEvent":80,"./getTextContentAccessor":113,"./keyOf":125}],9:[function(e,t){"use strict";function n(e,t,n){e.insertBefore(t,e.childNodes[n]||null)}var r,o=e("./Danger"),i=e("./ReactMultiChildUpdateTypes"),a=e("./getTextContentAccessor"),s=e("./invariant"),u=a();r="textContent"===u?function(e,t){e.textContent=t}:function(e,t){for(;e.firstChild;)e.removeChild(e.firstChild);if(t){var n=e.ownerDocument||document;e.appendChild(n.createTextNode(t))}};var c={dangerouslyReplaceNodeWithMarkup:o.dangerouslyReplaceNodeWithMarkup,updateTextContent:r,processUpdates:function(e,t){for(var a,u=null,c=null,l=0;a=e[l];l++)if(a.type===i.MOVE_EXISTING||a.type===i.REMOVE_NODE){var p=a.fromIndex,d=a.parentNode.childNodes[p],f=a.parentID;s(d),u=u||{},u[f]=u[f]||[],u[f][p]=d,c=c||[],c.push(d)}var h=o.dangerouslyRenderMarkup(t);if(c)for(var v=0;v<c.length;v++)c[v].parentNode.removeChild(c[v]);for(var m=0;a=e[m];m++)switch(a.type){case i.INSERT_MARKUP:n(a.parentNode,h[a.markupIndex],a.toIndex);break;case i.MOVE_EXISTING:n(a.parentNode,u[a.parentID][a.fromIndex],a.toIndex);break;case i.TEXT_CONTENT:r(a.parentNode,a.textContent);break;case i.REMOVE_NODE:}}};t.exports=c},{"./Danger":12,"./ReactMultiChildUpdateTypes":61,"./getTextContentAccessor":113,"./invariant":118}],10:[function(e,t){"use strict";var n=e("./invariant"),r={MUST_USE_ATTRIBUTE:1,MUST_USE_PROPERTY:2,HAS_SIDE_EFFECTS:4,HAS_BOOLEAN_VALUE:8,HAS_NUMERIC_VALUE:16,HAS_POSITIVE_NUMERIC_VALUE:48,HAS_OVERLOADED_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(e){var t=e.Properties||{},o=e.DOMAttributeNames||{},a=e.DOMPropertyNames||{},s=e.DOMMutationMethods||{};e.isCustomAttribute&&i._isCustomAttributeFunctions.push(e.isCustomAttribute);for(var u in t){n(!i.isStandardName.hasOwnProperty(u)),i.isStandardName[u]=!0;var c=u.toLowerCase();if(i.getPossibleStandardName[c]=u,o.hasOwnProperty(u)){var l=o[u];i.getPossibleStandardName[l]=u,i.getAttributeName[u]=l}else i.getAttributeName[u]=c;i.getPropertyName[u]=a.hasOwnProperty(u)?a[u]:u,i.getMutationMethod[u]=s.hasOwnProperty(u)?s[u]:null;var p=t[u];i.mustUseAttribute[u]=p&r.MUST_USE_ATTRIBUTE,i.mustUseProperty[u]=p&r.MUST_USE_PROPERTY,i.hasSideEffects[u]=p&r.HAS_SIDE_EFFECTS,i.hasBooleanValue[u]=p&r.HAS_BOOLEAN_VALUE,i.hasNumericValue[u]=p&r.HAS_NUMERIC_VALUE,i.hasPositiveNumericValue[u]=p&r.HAS_POSITIVE_NUMERIC_VALUE,i.hasOverloadedBooleanValue[u]=p&r.HAS_OVERLOADED_BOOLEAN_VALUE,n(!i.mustUseAttribute[u]||!i.mustUseProperty[u]),n(i.mustUseProperty[u]||!i.hasSideEffects[u]),n(!!i.hasBooleanValue[u]+!!i.hasNumericValue[u]+!!i.hasOverloadedBooleanValue[u]<=1)}}},o={},i={ID_ATTRIBUTE_NAME:"data-reactid",isStandardName:{},getPossibleStandardName:{},getAttributeName:{},getPropertyName:{},getMutationMethod:{},mustUseAttribute:{},mustUseProperty:{},hasSideEffects:{},hasBooleanValue:{},hasNumericValue:{},hasPositiveNumericValue:{},hasOverloadedBooleanValue:{},_isCustomAttributeFunctions:[],isCustomAttribute:function(e){for(var t=0;t<i._isCustomAttributeFunctions.length;t++){var n=i._isCustomAttributeFunctions[t];if(n(e))return!0}return!1},getDefaultValueForProperty:function(e,t){var n,r=o[e];return r||(o[e]=r={}),t in r||(n=document.createElement(e),r[t]=n[t]),r[t]},injection:r};t.exports=i},{"./invariant":118}],11:[function(e,t){"use strict";function n(e,t){return null==t||r.hasBooleanValue[e]&&!t||r.hasNumericValue[e]&&isNaN(t)||r.hasPositiveNumericValue[e]&&1>t||r.hasOverloadedBooleanValue[e]&&t===!1}var r=e("./DOMProperty"),o=e("./escapeTextForBrowser"),i=e("./memoizeStringOnly"),a=(e("./warning"),i(function(e){return o(e)+'="'})),s={createMarkupForID:function(e){return a(r.ID_ATTRIBUTE_NAME)+o(e)+'"'},createMarkupForProperty:function(e,t){if(r.isStandardName.hasOwnProperty(e)&&r.isStandardName[e]){if(n(e,t))return"";var i=r.getAttributeName[e];return r.hasBooleanValue[e]||r.hasOverloadedBooleanValue[e]&&t===!0?o(i):a(i)+o(t)+'"'}return r.isCustomAttribute(e)?null==t?"":a(e)+o(t)+'"':null},setValueForProperty:function(e,t,o){if(r.isStandardName.hasOwnProperty(t)&&r.isStandardName[t]){var i=r.getMutationMethod[t];if(i)i(e,o);else if(n(t,o))this.deleteValueForProperty(e,t);else if(r.mustUseAttribute[t])e.setAttribute(r.getAttributeName[t],""+o);else{var a=r.getPropertyName[t];r.hasSideEffects[t]&&e[a]===o||(e[a]=o)}}else r.isCustomAttribute(t)&&(null==o?e.removeAttribute(t):e.setAttribute(t,""+o))},deleteValueForProperty:function(e,t){if(r.isStandardName.hasOwnProperty(t)&&r.isStandardName[t]){var n=r.getMutationMethod[t];if(n)n(e,void 0);else if(r.mustUseAttribute[t])e.removeAttribute(r.getAttributeName[t]);else{var o=r.getPropertyName[t],i=r.getDefaultValueForProperty(e.nodeName,o);r.hasSideEffects[t]&&e[o]===i||(e[o]=i)}}else r.isCustomAttribute(t)&&e.removeAttribute(t)}};t.exports=s},{"./DOMProperty":10,"./escapeTextForBrowser":102,"./memoizeStringOnly":127,"./warning":139}],12:[function(e,t){"use strict";function n(e){return e.substring(1,e.indexOf(" "))}var r=e("./ExecutionEnvironment"),o=e("./createNodesFromMarkup"),i=e("./emptyFunction"),a=e("./getMarkupWrap"),s=e("./invariant"),u=/^(<[^ \/>]+)/,c="data-danger-index",l={dangerouslyRenderMarkup:function(e){s(r.canUseDOM);for(var t,l={},p=0;p<e.length;p++)s(e[p]),t=n(e[p]),t=a(t)?t:"*",l[t]=l[t]||[],l[t][p]=e[p];var d=[],f=0;for(t in l)if(l.hasOwnProperty(t)){var h=l[t];for(var v in h)if(h.hasOwnProperty(v)){var m=h[v];h[v]=m.replace(u,"$1 "+c+'="'+v+'" ')}var g=o(h.join(""),i);for(p=0;p<g.length;++p){var y=g[p];y.hasAttribute&&y.hasAttribute(c)&&(v=+y.getAttribute(c),y.removeAttribute(c),s(!d.hasOwnProperty(v)),d[v]=y,f+=1)}}return s(f===d.length),s(d.length===e.length),d},dangerouslyReplaceNodeWithMarkup:function(e,t){s(r.canUseDOM),s(t),s("html"!==e.tagName.toLowerCase());var n=o(t,i)[0];e.parentNode.replaceChild(n,e)}};t.exports=l},{"./ExecutionEnvironment":21,"./createNodesFromMarkup":98,"./emptyFunction":100,"./getMarkupWrap":110,"./invariant":118}],13:[function(e,t){"use strict";var n=e("./keyOf"),r=[n({ResponderEventPlugin:null}),n({SimpleEventPlugin:null}),n({TapEventPlugin:null}),n({EnterLeaveEventPlugin:null}),n({ChangeEventPlugin:null}),n({SelectEventPlugin:null}),n({CompositionEventPlugin:null}),n({BeforeInputEventPlugin:null}),n({AnalyticsEventPlugin:null}),n({MobileSafariClickEventPlugin:null})];t.exports=r},{"./keyOf":125}],14:[function(e,t){"use strict";var n=e("./EventConstants"),r=e("./EventPropagators"),o=e("./SyntheticMouseEvent"),i=e("./ReactMount"),a=e("./keyOf"),s=n.topLevelTypes,u=i.getFirstReactDOM,c={mouseEnter:{registrationName:a({onMouseEnter:null}),dependencies:[s.topMouseOut,s.topMouseOver]},mouseLeave:{registrationName:a({onMouseLeave:null}),dependencies:[s.topMouseOut,s.topMouseOver]}},l=[null,null],p={eventTypes:c,extractEvents:function(e,t,n,a){if(e===s.topMouseOver&&(a.relatedTarget||a.fromElement))return null;if(e!==s.topMouseOut&&e!==s.topMouseOver)return null;var p;if(t.window===t)p=t;else{var d=t.ownerDocument;p=d?d.defaultView||d.parentWindow:window}var f,h;if(e===s.topMouseOut?(f=t,h=u(a.relatedTarget||a.toElement)||p):(f=p,h=t),f===h)return null;var v=f?i.getID(f):"",m=h?i.getID(h):"",g=o.getPooled(c.mouseLeave,v,a);g.type="mouseleave",g.target=f,g.relatedTarget=h;var y=o.getPooled(c.mouseEnter,m,a);return y.type="mouseenter",y.target=h,y.relatedTarget=f,r.accumulateEnterLeaveDispatches(g,y,v,m),l[0]=g,l[1]=y,l}};t.exports=p},{"./EventConstants":15,"./EventPropagators":20,"./ReactMount":59,"./SyntheticMouseEvent":86,"./keyOf":125}],15:[function(e,t){"use strict";var n=e("./keyMirror"),r=n({bubbled:null,captured:null}),o=n({topBlur:null,topChange:null,topClick:null,topCompositionEnd:null,topCompositionStart:null,topCompositionUpdate:null,topContextMenu:null,topCopy:null,topCut:null,topDoubleClick:null,topDrag:null,topDragEnd:null,topDragEnter:null,topDragExit:null,topDragLeave:null,topDragOver:null,topDragStart:null,topDrop:null,topError:null,topFocus:null,topInput:null,topKeyDown:null,topKeyPress:null,topKeyUp:null,topLoad:null,topMouseDown:null,topMouseMove:null,topMouseOut:null,topMouseOver:null,topMouseUp:null,topPaste:null,topReset:null,topScroll:null,topSelectionChange:null,topSubmit:null,topTextInput:null,topTouchCancel:null,topTouchEnd:null,topTouchMove:null,topTouchStart:null,topWheel:null}),i={topLevelTypes:o,PropagationPhases:r};t.exports=i},{"./keyMirror":124}],16:[function(e,t){var n=e("./emptyFunction"),r={listen:function(e,t,n){return e.addEventListener?(e.addEventListener(t,n,!1),{remove:function(){e.removeEventListener(t,n,!1)}}):e.attachEvent?(e.attachEvent("on"+t,n),{remove:function(){e.detachEvent("on"+t,n)}}):void 0},capture:function(e,t,r){return e.addEventListener?(e.addEventListener(t,r,!0),{remove:function(){e.removeEventListener(t,r,!0)}}):{remove:n}},registerDefault:function(){}};t.exports=r},{"./emptyFunction":100}],17:[function(e,t){"use strict";var n=e("./EventPluginRegistry"),r=e("./EventPluginUtils"),o=e("./accumulate"),i=e("./forEachAccumulated"),a=e("./invariant"),s=(e("./isEventSupported"),e("./monitorCodeUse"),{}),u=null,c=function(e){if(e){var t=r.executeDispatch,o=n.getPluginModuleForEvent(e);o&&o.executeDispatch&&(t=o.executeDispatch),r.executeDispatchesInOrder(e,t),e.isPersistent()||e.constructor.release(e)}},l=null,p={injection:{injectMount:r.injection.injectMount,injectInstanceHandle:function(e){l=e},getInstanceHandle:function(){return l},injectEventPluginOrder:n.injectEventPluginOrder,injectEventPluginsByName:n.injectEventPluginsByName},eventNameDispatchConfigs:n.eventNameDispatchConfigs,registrationNameModules:n.registrationNameModules,putListener:function(e,t,n){a(!n||"function"==typeof n);var r=s[t]||(s[t]={});r[e]=n},getListener:function(e,t){var n=s[t];return n&&n[e]},deleteListener:function(e,t){var n=s[t];n&&delete n[e]},deleteAllListeners:function(e){for(var t in s)delete s[t][e]},extractEvents:function(e,t,r,i){for(var a,s=n.plugins,u=0,c=s.length;c>u;u++){var l=s[u];if(l){var p=l.extractEvents(e,t,r,i);p&&(a=o(a,p))}}return a},enqueueEvents:function(e){e&&(u=o(u,e))},processEventQueue:function(){var e=u;u=null,i(e,c),a(!u)},__purge:function(){s={}},__getListenerBank:function(){return s}};t.exports=p},{"./EventPluginRegistry":18,"./EventPluginUtils":19,"./accumulate":92,"./forEachAccumulated":105,"./invariant":118,"./isEventSupported":119,"./monitorCodeUse":132}],18:[function(e,t){"use strict";function n(){if(a)for(var e in s){var t=s[e],n=a.indexOf(e);if(i(n>-1),!u.plugins[n]){i(t.extractEvents),u.plugins[n]=t;var o=t.eventTypes;for(var c in o)i(r(o[c],t,c))}}}function r(e,t,n){i(!u.eventNameDispatchConfigs.hasOwnProperty(n)),u.eventNameDispatchConfigs[n]=e;var r=e.phasedRegistrationNames;if(r){for(var a in r)if(r.hasOwnProperty(a)){var s=r[a];o(s,t,n)}return!0}return e.registrationName?(o(e.registrationName,t,n),!0):!1}function o(e,t,n){i(!u.registrationNameModules[e]),u.registrationNameModules[e]=t,u.registrationNameDependencies[e]=t.eventTypes[n].dependencies}var i=e("./invariant"),a=null,s={},u={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(e){i(!a),a=Array.prototype.slice.call(e),n()},injectEventPluginsByName:function(e){var t=!1;for(var r in e)if(e.hasOwnProperty(r)){var o=e[r];s.hasOwnProperty(r)&&s[r]===o||(i(!s[r]),s[r]=o,t=!0)}t&&n()},getPluginModuleForEvent:function(e){var t=e.dispatchConfig;if(t.registrationName)return u.registrationNameModules[t.registrationName]||null;for(var n in t.phasedRegistrationNames)if(t.phasedRegistrationNames.hasOwnProperty(n)){var r=u.registrationNameModules[t.phasedRegistrationNames[n]];if(r)return r}return null},_resetEventPlugins:function(){a=null;for(var e in s)s.hasOwnProperty(e)&&delete s[e];u.plugins.length=0;var t=u.eventNameDispatchConfigs;for(var n in t)t.hasOwnProperty(n)&&delete t[n];var r=u.registrationNameModules;for(var o in r)r.hasOwnProperty(o)&&delete r[o]}};t.exports=u},{"./invariant":118}],19:[function(e,t){"use strict";function n(e){return e===v.topMouseUp||e===v.topTouchEnd||e===v.topTouchCancel}function r(e){return e===v.topMouseMove||e===v.topTouchMove}function o(e){return e===v.topMouseDown||e===v.topTouchStart}function i(e,t){var n=e._dispatchListeners,r=e._dispatchIDs;if(Array.isArray(n))for(var o=0;o<n.length&&!e.isPropagationStopped();o++)t(e,n[o],r[o]);else n&&t(e,n,r)}function a(e,t,n){e.currentTarget=h.Mount.getNode(n);var r=t(e,n);return e.currentTarget=null,r}function s(e,t){i(e,t),e._dispatchListeners=null,e._dispatchIDs=null}function u(e){var t=e._dispatchListeners,n=e._dispatchIDs;if(Array.isArray(t)){for(var r=0;r<t.length&&!e.isPropagationStopped();r++)if(t[r](e,n[r]))return n[r]}else if(t&&t(e,n))return n;return null}function c(e){var t=u(e);return e._dispatchIDs=null,e._dispatchListeners=null,t}function l(e){var t=e._dispatchListeners,n=e._dispatchIDs;f(!Array.isArray(t));var r=t?t(e,n):null;return e._dispatchListeners=null,e._dispatchIDs=null,r}function p(e){return!!e._dispatchListeners}var d=e("./EventConstants"),f=e("./invariant"),h={Mount:null,injectMount:function(e){h.Mount=e}},v=d.topLevelTypes,m={isEndish:n,isMoveish:r,isStartish:o,executeDirectDispatch:l,executeDispatch:a,executeDispatchesInOrder:s,executeDispatchesInOrderStopAtTrue:c,hasDispatches:p,injection:h,useTouchEvents:!1};t.exports=m},{"./EventConstants":15,"./invariant":118}],20:[function(e,t){"use strict";function n(e,t,n){var r=t.dispatchConfig.phasedRegistrationNames[n];return v(e,r)}function r(e,t,r){var o=t?h.bubbled:h.captured,i=n(e,r,o);i&&(r._dispatchListeners=d(r._dispatchListeners,i),r._dispatchIDs=d(r._dispatchIDs,e))}function o(e){e&&e.dispatchConfig.phasedRegistrationNames&&p.injection.getInstanceHandle().traverseTwoPhase(e.dispatchMarker,r,e)}function i(e,t,n){if(n&&n.dispatchConfig.registrationName){var r=n.dispatchConfig.registrationName,o=v(e,r);o&&(n._dispatchListeners=d(n._dispatchListeners,o),n._dispatchIDs=d(n._dispatchIDs,e))}}function a(e){e&&e.dispatchConfig.registrationName&&i(e.dispatchMarker,null,e)}function s(e){f(e,o)}function u(e,t,n,r){p.injection.getInstanceHandle().traverseEnterLeave(n,r,i,e,t)}function c(e){f(e,a)}var l=e("./EventConstants"),p=e("./EventPluginHub"),d=e("./accumulate"),f=e("./forEachAccumulated"),h=l.PropagationPhases,v=p.getListener,m={accumulateTwoPhaseDispatches:s,accumulateDirectDispatches:c,accumulateEnterLeaveDispatches:u};t.exports=m},{"./EventConstants":15,"./EventPluginHub":17,"./accumulate":92,"./forEachAccumulated":105}],21:[function(e,t){"use strict";var n=!("undefined"==typeof window||!window.document||!window.document.createElement),r={canUseDOM:n,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:n&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:n&&!!window.screen,isInWorker:!n};t.exports=r},{}],22:[function(e,t){"use strict";var n,r=e("./DOMProperty"),o=e("./ExecutionEnvironment"),i=r.injection.MUST_USE_ATTRIBUTE,a=r.injection.MUST_USE_PROPERTY,s=r.injection.HAS_BOOLEAN_VALUE,u=r.injection.HAS_SIDE_EFFECTS,c=r.injection.HAS_NUMERIC_VALUE,l=r.injection.HAS_POSITIVE_NUMERIC_VALUE,p=r.injection.HAS_OVERLOADED_BOOLEAN_VALUE;if(o.canUseDOM){var d=document.implementation;n=d&&d.hasFeature&&d.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")}var f={isCustomAttribute:RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),Properties:{accept:null,accessKey:null,action:null,allowFullScreen:i|s,allowTransparency:i,alt:null,async:s,autoComplete:null,autoPlay:s,cellPadding:null,cellSpacing:null,charSet:i,checked:a|s,className:n?i:a,cols:i|l,colSpan:null,content:null,contentEditable:null,contextMenu:i,controls:a|s,coords:null,crossOrigin:null,data:null,dateTime:i,defer:s,dir:null,disabled:i|s,download:p,draggable:null,encType:null,form:i,formNoValidate:s,frameBorder:i,height:i,hidden:i|s,href:null,hrefLang:null,htmlFor:null,httpEquiv:null,icon:null,id:a,label:null,lang:null,list:null,loop:a|s,max:null,maxLength:i,mediaGroup:null,method:null,min:null,multiple:a|s,muted:a|s,name:null,noValidate:s,pattern:null,placeholder:null,poster:null,preload:null,radioGroup:null,readOnly:a|s,rel:null,required:s,role:i,rows:i|l,rowSpan:null,sandbox:null,scope:null,scrollLeft:a,scrolling:null,scrollTop:a,seamless:i|s,selected:a|s,shape:null,size:i|l,span:l,spellCheck:null,src:null,srcDoc:a,srcSet:null,start:c,step:null,style:null,tabIndex:null,target:null,title:null,type:null,useMap:null,value:a|u,width:i,wmode:i,autoCapitalize:null,autoCorrect:null,itemProp:i,itemScope:i|s,itemType:i,property:null},DOMAttributeNames:{className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{autoCapitalize:"autocapitalize",autoComplete:"autocomplete",autoCorrect:"autocorrect",autoFocus:"autofocus",autoPlay:"autoplay",encType:"enctype",hrefLang:"hreflang",radioGroup:"radiogroup",spellCheck:"spellcheck",srcDoc:"srcdoc",srcSet:"srcset"}};t.exports=f},{"./DOMProperty":10,"./ExecutionEnvironment":21}],23:[function(e,t){"use strict";function n(e){u(null==e.props.checkedLink||null==e.props.valueLink)}function r(e){n(e),u(null==e.props.value&&null==e.props.onChange)}function o(e){n(e),u(null==e.props.checked&&null==e.props.onChange)}function i(e){this.props.valueLink.requestChange(e.target.value)}function a(e){this.props.checkedLink.requestChange(e.target.checked)}var s=e("./ReactPropTypes"),u=e("./invariant"),c={button:!0,checkbox:!0,image:!0,hidden:!0,radio:!0,reset:!0,submit:!0},l={Mixin:{propTypes:{value:function(e,t){return!e[t]||c[e.type]||e.onChange||e.readOnly||e.disabled?void 0:new Error("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.")},checked:function(e,t){return!e[t]||e.onChange||e.readOnly||e.disabled?void 0:new Error("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.")},onChange:s.func}},getValue:function(e){return e.props.valueLink?(r(e),e.props.valueLink.value):e.props.value},getChecked:function(e){return e.props.checkedLink?(o(e),e.props.checkedLink.value):e.props.checked},getOnChange:function(e){return e.props.valueLink?(r(e),i):e.props.checkedLink?(o(e),a):e.props.onChange}};t.exports=l},{"./ReactPropTypes":67,"./invariant":118}],24:[function(e,t){"use strict";function n(e){e.remove()}var r=e("./ReactBrowserEventEmitter"),o=e("./accumulate"),i=e("./forEachAccumulated"),a=e("./invariant"),s={trapBubbledEvent:function(e,t){a(this.isMounted());var n=r.trapBubbledEvent(e,t,this.getDOMNode());this._localEventListeners=o(this._localEventListeners,n)},componentWillUnmount:function(){this._localEventListeners&&i(this._localEventListeners,n)}};t.exports=s},{"./ReactBrowserEventEmitter":29,"./accumulate":92,"./forEachAccumulated":105,"./invariant":118}],25:[function(e,t){"use strict";var n=e("./EventConstants"),r=e("./emptyFunction"),o=n.topLevelTypes,i={eventTypes:null,extractEvents:function(e,t,n,i){if(e===o.topTouchStart){var a=i.target;a&&!a.onclick&&(a.onclick=r)}}};t.exports=i},{"./EventConstants":15,"./emptyFunction":100}],26:[function(e,t){"use strict";var n=e("./invariant"),r=function(e){var t=this;if(t.instancePool.length){var n=t.instancePool.pop();return t.call(n,e),n}return new t(e)},o=function(e,t){var n=this;if(n.instancePool.length){var r=n.instancePool.pop();return n.call(r,e,t),r}return new n(e,t)},i=function(e,t,n){var r=this;if(r.instancePool.length){var o=r.instancePool.pop();return r.call(o,e,t,n),o}return new r(e,t,n)},a=function(e,t,n,r,o){var i=this;if(i.instancePool.length){var a=i.instancePool.pop();return i.call(a,e,t,n,r,o),a}return new i(e,t,n,r,o)},s=function(e){var t=this;n(e instanceof t),e.destructor&&e.destructor(),t.instancePool.length<t.poolSize&&t.instancePool.push(e)},u=10,c=r,l=function(e,t){var n=e;return n.instancePool=[],n.getPooled=t||c,n.poolSize||(n.poolSize=u),n.release=s,n},p={addPoolingTo:l,oneArgumentPooler:r,twoArgumentPooler:o,threeArgumentPooler:i,fiveArgumentPooler:a};t.exports=p},{"./invariant":118}],27:[function(e,t){"use strict";var n=e("./DOMPropertyOperations"),r=e("./EventPluginUtils"),o=e("./ReactChildren"),i=e("./ReactComponent"),a=e("./ReactCompositeComponent"),s=e("./ReactContext"),u=e("./ReactCurrentOwner"),c=e("./ReactDescriptor"),l=e("./ReactDOM"),p=e("./ReactDOMComponent"),d=e("./ReactDefaultInjection"),f=e("./ReactInstanceHandles"),h=e("./ReactMount"),v=e("./ReactMultiChild"),m=e("./ReactPerf"),g=e("./ReactPropTypes"),y=e("./ReactServerRendering"),C=e("./ReactTextComponent"),E=e("./onlyChild");d.inject();var R={Children:{map:o.map,forEach:o.forEach,count:o.count,only:E},DOM:l,PropTypes:g,initializeTouchEvents:function(e){r.useTouchEvents=e},createClass:a.createClass,createDescriptor:function(e){var t=Array.prototype.slice.call(arguments,1);return e.apply(null,t)},constructAndRenderComponent:h.constructAndRenderComponent,constructAndRenderComponentByID:h.constructAndRenderComponentByID,renderComponent:m.measure("React","renderComponent",h.renderComponent),renderComponentToString:y.renderComponentToString,renderComponentToStaticMarkup:y.renderComponentToStaticMarkup,unmountComponentAtNode:h.unmountComponentAtNode,isValidClass:c.isValidFactory,isValidComponent:c.isValidDescriptor,withContext:s.withContext,__internals:{Component:i,CurrentOwner:u,DOMComponent:p,DOMPropertyOperations:n,InstanceHandles:f,Mount:h,MultiChild:v,TextComponent:C}};R.version="0.11.1",t.exports=R},{"./DOMPropertyOperations":11,"./EventPluginUtils":19,"./ReactChildren":30,"./ReactComponent":31,"./ReactCompositeComponent":33,"./ReactContext":34,"./ReactCurrentOwner":35,"./ReactDOM":36,"./ReactDOMComponent":38,"./ReactDefaultInjection":48,"./ReactDescriptor":49,"./ReactInstanceHandles":57,"./ReactMount":59,"./ReactMultiChild":60,"./ReactPerf":63,"./ReactPropTypes":67,"./ReactServerRendering":71,"./ReactTextComponent":73,"./onlyChild":133}],28:[function(e,t){"use strict";var n=e("./ReactEmptyComponent"),r=e("./ReactMount"),o=e("./invariant"),i={getDOMNode:function(){return o(this.isMounted()),n.isNullComponentID(this._rootNodeID)?null:r.getNode(this._rootNodeID)}};t.exports=i},{"./ReactEmptyComponent":51,"./ReactMount":59,"./invariant":118}],29:[function(e,t){"use strict";function n(e){return Object.prototype.hasOwnProperty.call(e,h)||(e[h]=d++,l[e[h]]={}),l[e[h]]}var r=e("./EventConstants"),o=e("./EventPluginHub"),i=e("./EventPluginRegistry"),a=e("./ReactEventEmitterMixin"),s=e("./ViewportMetrics"),u=e("./isEventSupported"),c=e("./merge"),l={},p=!1,d=0,f={topBlur:"blur",topChange:"change",topClick:"click",topCompositionEnd:"compositionend",topCompositionStart:"compositionstart",topCompositionUpdate:"compositionupdate",topContextMenu:"contextmenu",topCopy:"copy",topCut:"cut",topDoubleClick:"dblclick",topDrag:"drag",topDragEnd:"dragend",topDragEnter:"dragenter",topDragExit:"dragexit",topDragLeave:"dragleave",topDragOver:"dragover",topDragStart:"dragstart",topDrop:"drop",topFocus:"focus",topInput:"input",topKeyDown:"keydown",topKeyPress:"keypress",topKeyUp:"keyup",topMouseDown:"mousedown",topMouseMove:"mousemove",topMouseOut:"mouseout",topMouseOver:"mouseover",topMouseUp:"mouseup",topPaste:"paste",topScroll:"scroll",topSelectionChange:"selectionchange",topTextInput:"textInput",topTouchCancel:"touchcancel",topTouchEnd:"touchend",topTouchMove:"touchmove",topTouchStart:"touchstart",topWheel:"wheel"},h="_reactListenersID"+String(Math.random()).slice(2),v=c(a,{ReactEventListener:null,injection:{injectReactEventListener:function(e){e.setHandleTopLevel(v.handleTopLevel),v.ReactEventListener=e
-}},setEnabled:function(e){v.ReactEventListener&&v.ReactEventListener.setEnabled(e)},isEnabled:function(){return!(!v.ReactEventListener||!v.ReactEventListener.isEnabled())},listenTo:function(e,t){for(var o=t,a=n(o),s=i.registrationNameDependencies[e],c=r.topLevelTypes,l=0,p=s.length;p>l;l++){var d=s[l];a.hasOwnProperty(d)&&a[d]||(d===c.topWheel?u("wheel")?v.ReactEventListener.trapBubbledEvent(c.topWheel,"wheel",o):u("mousewheel")?v.ReactEventListener.trapBubbledEvent(c.topWheel,"mousewheel",o):v.ReactEventListener.trapBubbledEvent(c.topWheel,"DOMMouseScroll",o):d===c.topScroll?u("scroll",!0)?v.ReactEventListener.trapCapturedEvent(c.topScroll,"scroll",o):v.ReactEventListener.trapBubbledEvent(c.topScroll,"scroll",v.ReactEventListener.WINDOW_HANDLE):d===c.topFocus||d===c.topBlur?(u("focus",!0)?(v.ReactEventListener.trapCapturedEvent(c.topFocus,"focus",o),v.ReactEventListener.trapCapturedEvent(c.topBlur,"blur",o)):u("focusin")&&(v.ReactEventListener.trapBubbledEvent(c.topFocus,"focusin",o),v.ReactEventListener.trapBubbledEvent(c.topBlur,"focusout",o)),a[c.topBlur]=!0,a[c.topFocus]=!0):f.hasOwnProperty(d)&&v.ReactEventListener.trapBubbledEvent(d,f[d],o),a[d]=!0)}},trapBubbledEvent:function(e,t,n){return v.ReactEventListener.trapBubbledEvent(e,t,n)},trapCapturedEvent:function(e,t,n){return v.ReactEventListener.trapCapturedEvent(e,t,n)},ensureScrollValueMonitoring:function(){if(!p){var e=s.refreshScrollValues;v.ReactEventListener.monitorScrollValue(e),p=!0}},eventNameDispatchConfigs:o.eventNameDispatchConfigs,registrationNameModules:o.registrationNameModules,putListener:o.putListener,getListener:o.getListener,deleteListener:o.deleteListener,deleteAllListeners:o.deleteAllListeners});t.exports=v},{"./EventConstants":15,"./EventPluginHub":17,"./EventPluginRegistry":18,"./ReactEventEmitterMixin":53,"./ViewportMetrics":91,"./isEventSupported":119,"./merge":128}],30:[function(e,t){"use strict";function n(e,t){this.forEachFunction=e,this.forEachContext=t}function r(e,t,n,r){var o=e;o.forEachFunction.call(o.forEachContext,t,r)}function o(e,t,o){if(null==e)return e;var i=n.getPooled(t,o);p(e,r,i),n.release(i)}function i(e,t,n){this.mapResult=e,this.mapFunction=t,this.mapContext=n}function a(e,t,n,r){var o=e,i=o.mapResult,a=!i.hasOwnProperty(n);if(a){var s=o.mapFunction.call(o.mapContext,t,r);i[n]=s}}function s(e,t,n){if(null==e)return e;var r={},o=i.getPooled(r,t,n);return p(e,a,o),i.release(o),r}function u(){return null}function c(e){return p(e,u,null)}var l=e("./PooledClass"),p=e("./traverseAllChildren"),d=(e("./warning"),l.twoArgumentPooler),f=l.threeArgumentPooler;l.addPoolingTo(n,d),l.addPoolingTo(i,f);var h={forEach:o,map:s,count:c};t.exports=h},{"./PooledClass":26,"./traverseAllChildren":138,"./warning":139}],31:[function(e,t){"use strict";var n=e("./ReactDescriptor"),r=e("./ReactOwner"),o=e("./ReactUpdates"),i=e("./invariant"),a=e("./keyMirror"),s=e("./merge"),u=a({MOUNTED:null,UNMOUNTED:null}),c=!1,l=null,p=null,d={injection:{injectEnvironment:function(e){i(!c),p=e.mountImageIntoNode,l=e.unmountIDFromEnvironment,d.BackendIDOperations=e.BackendIDOperations,c=!0}},LifeCycle:u,BackendIDOperations:null,Mixin:{isMounted:function(){return this._lifeCycleState===u.MOUNTED},setProps:function(e,t){var n=this._pendingDescriptor||this._descriptor;this.replaceProps(s(n.props,e),t)},replaceProps:function(e,t){i(this.isMounted()),i(0===this._mountDepth),this._pendingDescriptor=n.cloneAndReplaceProps(this._pendingDescriptor||this._descriptor,e),o.enqueueUpdate(this,t)},_setPropsInternal:function(e,t){var r=this._pendingDescriptor||this._descriptor;this._pendingDescriptor=n.cloneAndReplaceProps(r,s(r.props,e)),o.enqueueUpdate(this,t)},construct:function(e){this.props=e.props,this._owner=e._owner,this._lifeCycleState=u.UNMOUNTED,this._pendingCallbacks=null,this._descriptor=e,this._pendingDescriptor=null},mountComponent:function(e,t,n){i(!this.isMounted());var o=this._descriptor.props;if(null!=o.ref){var a=this._descriptor._owner;r.addComponentAsRefTo(this,o.ref,a)}this._rootNodeID=e,this._lifeCycleState=u.MOUNTED,this._mountDepth=n},unmountComponent:function(){i(this.isMounted());var e=this.props;null!=e.ref&&r.removeComponentAsRefFrom(this,e.ref,this._owner),l(this._rootNodeID),this._rootNodeID=null,this._lifeCycleState=u.UNMOUNTED},receiveComponent:function(e,t){i(this.isMounted()),this._pendingDescriptor=e,this.performUpdateIfNecessary(t)},performUpdateIfNecessary:function(e){if(null!=this._pendingDescriptor){var t=this._descriptor,n=this._pendingDescriptor;this._descriptor=n,this.props=n.props,this._owner=n._owner,this._pendingDescriptor=null,this.updateComponent(e,t)}},updateComponent:function(e,t){var n=this._descriptor;(n._owner!==t._owner||n.props.ref!==t.props.ref)&&(null!=t.props.ref&&r.removeComponentAsRefFrom(this,t.props.ref,t._owner),null!=n.props.ref&&r.addComponentAsRefTo(this,n.props.ref,n._owner))},mountComponentIntoNode:function(e,t,n){var r=o.ReactReconcileTransaction.getPooled();r.perform(this._mountComponentIntoNode,this,e,t,r,n),o.ReactReconcileTransaction.release(r)},_mountComponentIntoNode:function(e,t,n,r){var o=this.mountComponent(e,n,0);p(o,t,r)},isOwnedBy:function(e){return this._owner===e},getSiblingByRef:function(e){var t=this._owner;return t&&t.refs?t.refs[e]:null}}};t.exports=d},{"./ReactDescriptor":49,"./ReactOwner":62,"./ReactUpdates":74,"./invariant":118,"./keyMirror":124,"./merge":128}],32:[function(e,t){"use strict";var n=e("./ReactDOMIDOperations"),r=e("./ReactMarkupChecksum"),o=e("./ReactMount"),i=e("./ReactPerf"),a=e("./ReactReconcileTransaction"),s=e("./getReactRootElementInContainer"),u=e("./invariant"),c=e("./setInnerHTML"),l=1,p=9,d={ReactReconcileTransaction:a,BackendIDOperations:n,unmountIDFromEnvironment:function(e){o.purgeID(e)},mountImageIntoNode:i.measure("ReactComponentBrowserEnvironment","mountImageIntoNode",function(e,t,n){if(u(t&&(t.nodeType===l||t.nodeType===p)),n){if(r.canReuseMarkup(e,s(t)))return;u(t.nodeType!==p)}u(t.nodeType!==p),c(t,e)})};t.exports=d},{"./ReactDOMIDOperations":40,"./ReactMarkupChecksum":58,"./ReactMount":59,"./ReactPerf":63,"./ReactReconcileTransaction":69,"./getReactRootElementInContainer":112,"./invariant":118,"./setInnerHTML":134}],33:[function(e,t){"use strict";function n(e){var t=e._owner||null;return t&&t.constructor&&t.constructor.displayName?" Check the render method of `"+t.constructor.displayName+"`.":""}function r(e,t){for(var n in t)t.hasOwnProperty(n)&&D("function"==typeof t[n])}function o(e,t){var n=N.hasOwnProperty(t)?N[t]:null;A.hasOwnProperty(t)&&D(n===_.OVERRIDE_BASE),e.hasOwnProperty(t)&&D(n===_.DEFINE_MANY||n===_.DEFINE_MANY_MERGED)}function i(e){var t=e._compositeLifeCycleState;D(e.isMounted()||t===S.MOUNTING),D(t!==S.RECEIVING_STATE),D(t!==S.UNMOUNTING)}function a(e,t){D(!h.isValidFactory(t)),D(!h.isValidDescriptor(t));var n=e.prototype;for(var r in t){var i=t[r];if(t.hasOwnProperty(r))if(o(n,r),w.hasOwnProperty(r))w[r](e,i);else{var a=N.hasOwnProperty(r),s=n.hasOwnProperty(r),u=i&&i.__reactDontBind,p="function"==typeof i,d=p&&!a&&!s&&!u;if(d)n.__reactAutoBindMap||(n.__reactAutoBindMap={}),n.__reactAutoBindMap[r]=i,n[r]=i;else if(s){var f=N[r];D(a&&(f===_.DEFINE_MANY_MERGED||f===_.DEFINE_MANY)),f===_.DEFINE_MANY_MERGED?n[r]=c(n[r],i):f===_.DEFINE_MANY&&(n[r]=l(n[r],i))}else n[r]=i}}}function s(e,t){if(t)for(var n in t){var r=t[n];if(t.hasOwnProperty(n)){var o=n in e,i=r;if(o){var a=e[n],s=typeof a,u=typeof r;D("function"===s&&"function"===u),i=l(a,r)}e[n]=i}}}function u(e,t){return D(e&&t&&"object"==typeof e&&"object"==typeof t),P(t,function(t,n){D(void 0===e[n]),e[n]=t}),e}function c(e,t){return function(){var n=e.apply(this,arguments),r=t.apply(this,arguments);return null==n?r:null==r?n:u(n,r)}}function l(e,t){return function(){e.apply(this,arguments),t.apply(this,arguments)}}var p=e("./ReactComponent"),d=e("./ReactContext"),f=e("./ReactCurrentOwner"),h=e("./ReactDescriptor"),v=(e("./ReactDescriptorValidator"),e("./ReactEmptyComponent")),m=e("./ReactErrorUtils"),g=e("./ReactOwner"),y=e("./ReactPerf"),C=e("./ReactPropTransferer"),E=e("./ReactPropTypeLocations"),R=(e("./ReactPropTypeLocationNames"),e("./ReactUpdates")),M=e("./instantiateReactComponent"),D=e("./invariant"),x=e("./keyMirror"),b=e("./merge"),O=e("./mixInto"),P=(e("./monitorCodeUse"),e("./mapObject")),I=e("./shouldUpdateReactComponent"),_=(e("./warning"),x({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null})),T=[],N={mixins:_.DEFINE_MANY,statics:_.DEFINE_MANY,propTypes:_.DEFINE_MANY,contextTypes:_.DEFINE_MANY,childContextTypes:_.DEFINE_MANY,getDefaultProps:_.DEFINE_MANY_MERGED,getInitialState:_.DEFINE_MANY_MERGED,getChildContext:_.DEFINE_MANY_MERGED,render:_.DEFINE_ONCE,componentWillMount:_.DEFINE_MANY,componentDidMount:_.DEFINE_MANY,componentWillReceiveProps:_.DEFINE_MANY,shouldComponentUpdate:_.DEFINE_ONCE,componentWillUpdate:_.DEFINE_MANY,componentDidUpdate:_.DEFINE_MANY,componentWillUnmount:_.DEFINE_MANY,updateComponent:_.OVERRIDE_BASE},w={displayName:function(e,t){e.displayName=t},mixins:function(e,t){if(t)for(var n=0;n<t.length;n++)a(e,t[n])},childContextTypes:function(e,t){r(e,t,E.childContext),e.childContextTypes=b(e.childContextTypes,t)},contextTypes:function(e,t){r(e,t,E.context),e.contextTypes=b(e.contextTypes,t)},getDefaultProps:function(e,t){e.getDefaultProps=e.getDefaultProps?c(e.getDefaultProps,t):t},propTypes:function(e,t){r(e,t,E.prop),e.propTypes=b(e.propTypes,t)},statics:function(e,t){s(e,t)}},S=x({MOUNTING:null,UNMOUNTING:null,RECEIVING_PROPS:null,RECEIVING_STATE:null}),A={construct:function(){p.Mixin.construct.apply(this,arguments),g.Mixin.construct.apply(this,arguments),this.state=null,this._pendingState=null,this.context=null,this._compositeLifeCycleState=null},isMounted:function(){return p.Mixin.isMounted.call(this)&&this._compositeLifeCycleState!==S.MOUNTING},mountComponent:y.measure("ReactCompositeComponent","mountComponent",function(e,t,n){p.Mixin.mountComponent.call(this,e,t,n),this._compositeLifeCycleState=S.MOUNTING,this.__reactAutoBindMap&&this._bindAutoBindMethods(),this.context=this._processContext(this._descriptor._context),this.props=this._processProps(this.props),this.state=this.getInitialState?this.getInitialState():null,D("object"==typeof this.state&&!Array.isArray(this.state)),this._pendingState=null,this._pendingForceUpdate=!1,this.componentWillMount&&(this.componentWillMount(),this._pendingState&&(this.state=this._pendingState,this._pendingState=null)),this._renderedComponent=M(this._renderValidatedComponent()),this._compositeLifeCycleState=null;var r=this._renderedComponent.mountComponent(e,t,n+1);return this.componentDidMount&&t.getReactMountReady().enqueue(this.componentDidMount,this),r}),unmountComponent:function(){this._compositeLifeCycleState=S.UNMOUNTING,this.componentWillUnmount&&this.componentWillUnmount(),this._compositeLifeCycleState=null,this._renderedComponent.unmountComponent(),this._renderedComponent=null,p.Mixin.unmountComponent.call(this)},setState:function(e,t){D("object"==typeof e||null==e),this.replaceState(b(this._pendingState||this.state,e),t)},replaceState:function(e,t){i(this),this._pendingState=e,this._compositeLifeCycleState!==S.MOUNTING&&R.enqueueUpdate(this,t)},_processContext:function(e){var t=null,n=this.constructor.contextTypes;if(n){t={};for(var r in n)t[r]=e[r]}return t},_processChildContext:function(e){var t=this.getChildContext&&this.getChildContext();if(this.constructor.displayName||"ReactCompositeComponent",t){D("object"==typeof this.constructor.childContextTypes);for(var n in t)D(n in this.constructor.childContextTypes);return b(e,t)}return e},_processProps:function(e){var t,n=this.constructor.defaultProps;if(n){t=b(e);for(var r in n)"undefined"==typeof t[r]&&(t[r]=n[r])}else t=e;return t},_checkPropTypes:function(e,t,r){var o=this.constructor.displayName;for(var i in e)if(e.hasOwnProperty(i)){var a=e[i](t,i,o,r);a instanceof Error&&n(this)}},performUpdateIfNecessary:function(e){var t=this._compositeLifeCycleState;if(t!==S.MOUNTING&&t!==S.RECEIVING_PROPS&&(null!=this._pendingDescriptor||null!=this._pendingState||this._pendingForceUpdate)){var n=this.context,r=this.props,o=this._descriptor;null!=this._pendingDescriptor&&(o=this._pendingDescriptor,n=this._processContext(o._context),r=this._processProps(o.props),this._pendingDescriptor=null,this._compositeLifeCycleState=S.RECEIVING_PROPS,this.componentWillReceiveProps&&this.componentWillReceiveProps(r,n)),this._compositeLifeCycleState=S.RECEIVING_STATE;var i=this._pendingState||this.state;this._pendingState=null;try{var a=this._pendingForceUpdate||!this.shouldComponentUpdate||this.shouldComponentUpdate(r,i,n);a?(this._pendingForceUpdate=!1,this._performComponentUpdate(o,r,i,n,e)):(this._descriptor=o,this.props=r,this.state=i,this.context=n,this._owner=o._owner)}finally{this._compositeLifeCycleState=null}}},_performComponentUpdate:function(e,t,n,r,o){var i=this._descriptor,a=this.props,s=this.state,u=this.context;this.componentWillUpdate&&this.componentWillUpdate(t,n,r),this._descriptor=e,this.props=t,this.state=n,this.context=r,this._owner=e._owner,this.updateComponent(o,i),this.componentDidUpdate&&o.getReactMountReady().enqueue(this.componentDidUpdate.bind(this,a,s,u),this)},receiveComponent:function(e,t){(e!==this._descriptor||null==e._owner)&&p.Mixin.receiveComponent.call(this,e,t)},updateComponent:y.measure("ReactCompositeComponent","updateComponent",function(e,t){p.Mixin.updateComponent.call(this,e,t);var n=this._renderedComponent,r=n._descriptor,o=this._renderValidatedComponent();if(I(r,o))n.receiveComponent(o,e);else{var i=this._rootNodeID,a=n._rootNodeID;n.unmountComponent(),this._renderedComponent=M(o);var s=this._renderedComponent.mountComponent(i,e,this._mountDepth+1);p.BackendIDOperations.dangerouslyReplaceNodeWithMarkupByID(a,s)}}),forceUpdate:function(e){var t=this._compositeLifeCycleState;D(this.isMounted()||t===S.MOUNTING),D(t!==S.RECEIVING_STATE&&t!==S.UNMOUNTING),this._pendingForceUpdate=!0,R.enqueueUpdate(this,e)},_renderValidatedComponent:y.measure("ReactCompositeComponent","_renderValidatedComponent",function(){var e,t=d.current;d.current=this._processChildContext(this._descriptor._context),f.current=this;try{e=this.render(),null===e||e===!1?(e=v.getEmptyComponent(),v.registerNullComponentID(this._rootNodeID)):v.deregisterNullComponentID(this._rootNodeID)}finally{d.current=t,f.current=null}return D(h.isValidDescriptor(e)),e}),_bindAutoBindMethods:function(){for(var e in this.__reactAutoBindMap)if(this.__reactAutoBindMap.hasOwnProperty(e)){var t=this.__reactAutoBindMap[e];this[e]=this._bindAutoBindMethod(m.guard(t,this.constructor.displayName+"."+e))}},_bindAutoBindMethod:function(e){var t=this,n=function(){return e.apply(t,arguments)};return n}},k=function(){};O(k,p.Mixin),O(k,g.Mixin),O(k,C.Mixin),O(k,A);var U={LifeCycle:S,Base:k,createClass:function(e){var t=function(e,t){this.construct(e,t)};t.prototype=new k,t.prototype.constructor=t,T.forEach(a.bind(null,t)),a(t,e),t.getDefaultProps&&(t.defaultProps=t.getDefaultProps()),D(t.prototype.render);for(var n in N)t.prototype[n]||(t.prototype[n]=null);var r=h.createFactory(t);return r},injection:{injectMixin:function(e){T.push(e)}}};t.exports=U},{"./ReactComponent":31,"./ReactContext":34,"./ReactCurrentOwner":35,"./ReactDescriptor":49,"./ReactDescriptorValidator":50,"./ReactEmptyComponent":51,"./ReactErrorUtils":52,"./ReactOwner":62,"./ReactPerf":63,"./ReactPropTransferer":64,"./ReactPropTypeLocationNames":65,"./ReactPropTypeLocations":66,"./ReactUpdates":74,"./instantiateReactComponent":117,"./invariant":118,"./keyMirror":124,"./mapObject":126,"./merge":128,"./mixInto":131,"./monitorCodeUse":132,"./shouldUpdateReactComponent":136,"./warning":139}],34:[function(e,t){"use strict";var n=e("./merge"),r={current:{},withContext:function(e,t){var o,i=r.current;r.current=n(i,e);try{o=t()}finally{r.current=i}return o}};t.exports=r},{"./merge":128}],35:[function(e,t){"use strict";var n={current:null};t.exports=n},{}],36:[function(e,t){"use strict";function n(e,t){var n=function(e){this.construct(e)};n.prototype=new o(t,e),n.prototype.constructor=n,n.displayName=t;var i=r.createFactory(n);return i}var r=e("./ReactDescriptor"),o=(e("./ReactDescriptorValidator"),e("./ReactDOMComponent")),i=e("./mergeInto"),a=e("./mapObject"),s=a({a:!1,abbr:!1,address:!1,area:!0,article:!1,aside:!1,audio:!1,b:!1,base:!0,bdi:!1,bdo:!1,big:!1,blockquote:!1,body:!1,br:!0,button:!1,canvas:!1,caption:!1,cite:!1,code:!1,col:!0,colgroup:!1,data:!1,datalist:!1,dd:!1,del:!1,details:!1,dfn:!1,div:!1,dl:!1,dt:!1,em:!1,embed:!0,fieldset:!1,figcaption:!1,figure:!1,footer:!1,form:!1,h1:!1,h2:!1,h3:!1,h4:!1,h5:!1,h6:!1,head:!1,header:!1,hr:!0,html:!1,i:!1,iframe:!1,img:!0,input:!0,ins:!1,kbd:!1,keygen:!0,label:!1,legend:!1,li:!1,link:!0,main:!1,map:!1,mark:!1,menu:!1,menuitem:!1,meta:!0,meter:!1,nav:!1,noscript:!1,object:!1,ol:!1,optgroup:!1,option:!1,output:!1,p:!1,param:!0,pre:!1,progress:!1,q:!1,rp:!1,rt:!1,ruby:!1,s:!1,samp:!1,script:!1,section:!1,select:!1,small:!1,source:!0,span:!1,strong:!1,style:!1,sub:!1,summary:!1,sup:!1,table:!1,tbody:!1,td:!1,textarea:!1,tfoot:!1,th:!1,thead:!1,time:!1,title:!1,tr:!1,track:!0,u:!1,ul:!1,"var":!1,video:!1,wbr:!0,circle:!1,defs:!1,ellipse:!1,g:!1,line:!1,linearGradient:!1,mask:!1,path:!1,pattern:!1,polygon:!1,polyline:!1,radialGradient:!1,rect:!1,stop:!1,svg:!1,text:!1,tspan:!1},n),u={injectComponentClasses:function(e){i(s,e)}};s.injection=u,t.exports=s},{"./ReactDOMComponent":38,"./ReactDescriptor":49,"./ReactDescriptorValidator":50,"./mapObject":126,"./mergeInto":130}],37:[function(e,t){"use strict";var n=e("./AutoFocusMixin"),r=e("./ReactBrowserComponentMixin"),o=e("./ReactCompositeComponent"),i=e("./ReactDOM"),a=e("./keyMirror"),s=i.button,u=a({onClick:!0,onDoubleClick:!0,onMouseDown:!0,onMouseMove:!0,onMouseUp:!0,onClickCapture:!0,onDoubleClickCapture:!0,onMouseDownCapture:!0,onMouseMoveCapture:!0,onMouseUpCapture:!0}),c=o.createClass({displayName:"ReactDOMButton",mixins:[n,r],render:function(){var e={};for(var t in this.props)!this.props.hasOwnProperty(t)||this.props.disabled&&u[t]||(e[t]=this.props[t]);return s(e,this.props.children)}});t.exports=c},{"./AutoFocusMixin":1,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36,"./keyMirror":124}],38:[function(e,t){"use strict";function n(e){e&&(v(null==e.children||null==e.dangerouslySetInnerHTML),v(null==e.style||"object"==typeof e.style))}function r(e,t,n,r){var o=p.findReactContainerForID(e);if(o){var i=o.nodeType===x?o.ownerDocument:o;E(t,i)}r.getPutListenerQueue().enqueuePutListener(e,t,n)}function o(e,t){this._tagOpen="<"+e,this._tagClose=t?"":"</"+e+">",this.tagName=e.toUpperCase()}var i=e("./CSSPropertyOperations"),a=e("./DOMProperty"),s=e("./DOMPropertyOperations"),u=e("./ReactBrowserComponentMixin"),c=e("./ReactComponent"),l=e("./ReactBrowserEventEmitter"),p=e("./ReactMount"),d=e("./ReactMultiChild"),f=e("./ReactPerf"),h=e("./escapeTextForBrowser"),v=e("./invariant"),m=e("./keyOf"),g=e("./merge"),y=e("./mixInto"),C=l.deleteListener,E=l.listenTo,R=l.registrationNameModules,M={string:!0,number:!0},D=m({style:null}),x=1;o.Mixin={mountComponent:f.measure("ReactDOMComponent","mountComponent",function(e,t,r){return c.Mixin.mountComponent.call(this,e,t,r),n(this.props),this._createOpenTagMarkupAndPutListeners(t)+this._createContentMarkup(t)+this._tagClose}),_createOpenTagMarkupAndPutListeners:function(e){var t=this.props,n=this._tagOpen;for(var o in t)if(t.hasOwnProperty(o)){var a=t[o];if(null!=a)if(R.hasOwnProperty(o))r(this._rootNodeID,o,a,e);else{o===D&&(a&&(a=t.style=g(t.style)),a=i.createMarkupForStyles(a));var u=s.createMarkupForProperty(o,a);u&&(n+=" "+u)}}if(e.renderToStaticMarkup)return n+">";var c=s.createMarkupForID(this._rootNodeID);return n+" "+c+">"},_createContentMarkup:function(e){var t=this.props.dangerouslySetInnerHTML;if(null!=t){if(null!=t.__html)return t.__html}else{var n=M[typeof this.props.children]?this.props.children:null,r=null!=n?null:this.props.children;if(null!=n)return h(n);if(null!=r){var o=this.mountChildren(r,e);return o.join("")}}return""},receiveComponent:function(e,t){(e!==this._descriptor||null==e._owner)&&c.Mixin.receiveComponent.call(this,e,t)},updateComponent:f.measure("ReactDOMComponent","updateComponent",function(e,t){n(this._descriptor.props),c.Mixin.updateComponent.call(this,e,t),this._updateDOMProperties(t.props,e),this._updateDOMChildren(t.props,e)}),_updateDOMProperties:function(e,t){var n,o,i,s=this.props;for(n in e)if(!s.hasOwnProperty(n)&&e.hasOwnProperty(n))if(n===D){var u=e[n];for(o in u)u.hasOwnProperty(o)&&(i=i||{},i[o]="")}else R.hasOwnProperty(n)?C(this._rootNodeID,n):(a.isStandardName[n]||a.isCustomAttribute(n))&&c.BackendIDOperations.deletePropertyByID(this._rootNodeID,n);for(n in s){var l=s[n],p=e[n];if(s.hasOwnProperty(n)&&l!==p)if(n===D)if(l&&(l=s.style=g(l)),p){for(o in p)!p.hasOwnProperty(o)||l&&l.hasOwnProperty(o)||(i=i||{},i[o]="");for(o in l)l.hasOwnProperty(o)&&p[o]!==l[o]&&(i=i||{},i[o]=l[o])}else i=l;else R.hasOwnProperty(n)?r(this._rootNodeID,n,l,t):(a.isStandardName[n]||a.isCustomAttribute(n))&&c.BackendIDOperations.updatePropertyByID(this._rootNodeID,n,l)}i&&c.BackendIDOperations.updateStylesByID(this._rootNodeID,i)},_updateDOMChildren:function(e,t){var n=this.props,r=M[typeof e.children]?e.children:null,o=M[typeof n.children]?n.children:null,i=e.dangerouslySetInnerHTML&&e.dangerouslySetInnerHTML.__html,a=n.dangerouslySetInnerHTML&&n.dangerouslySetInnerHTML.__html,s=null!=r?null:e.children,u=null!=o?null:n.children,l=null!=r||null!=i,p=null!=o||null!=a;null!=s&&null==u?this.updateChildren(null,t):l&&!p&&this.updateTextContent(""),null!=o?r!==o&&this.updateTextContent(""+o):null!=a?i!==a&&c.BackendIDOperations.updateInnerHTMLByID(this._rootNodeID,a):null!=u&&this.updateChildren(u,t)},unmountComponent:function(){this.unmountChildren(),l.deleteAllListeners(this._rootNodeID),c.Mixin.unmountComponent.call(this)}},y(o,c.Mixin),y(o,o.Mixin),y(o,d.Mixin),y(o,u),t.exports=o},{"./CSSPropertyOperations":4,"./DOMProperty":10,"./DOMPropertyOperations":11,"./ReactBrowserComponentMixin":28,"./ReactBrowserEventEmitter":29,"./ReactComponent":31,"./ReactMount":59,"./ReactMultiChild":60,"./ReactPerf":63,"./escapeTextForBrowser":102,"./invariant":118,"./keyOf":125,"./merge":128,"./mixInto":131}],39:[function(e,t){"use strict";var n=e("./EventConstants"),r=e("./LocalEventTrapMixin"),o=e("./ReactBrowserComponentMixin"),i=e("./ReactCompositeComponent"),a=e("./ReactDOM"),s=a.form,u=i.createClass({displayName:"ReactDOMForm",mixins:[o,r],render:function(){return this.transferPropsTo(s(null,this.props.children))},componentDidMount:function(){this.trapBubbledEvent(n.topLevelTypes.topReset,"reset"),this.trapBubbledEvent(n.topLevelTypes.topSubmit,"submit")}});t.exports=u},{"./EventConstants":15,"./LocalEventTrapMixin":24,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36}],40:[function(e,t){"use strict";var n=e("./CSSPropertyOperations"),r=e("./DOMChildrenOperations"),o=e("./DOMPropertyOperations"),i=e("./ReactMount"),a=e("./ReactPerf"),s=e("./invariant"),u=e("./setInnerHTML"),c={dangerouslySetInnerHTML:"`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.",style:"`style` must be set using `updateStylesByID()`."},l={updatePropertyByID:a.measure("ReactDOMIDOperations","updatePropertyByID",function(e,t,n){var r=i.getNode(e);s(!c.hasOwnProperty(t)),null!=n?o.setValueForProperty(r,t,n):o.deleteValueForProperty(r,t)}),deletePropertyByID:a.measure("ReactDOMIDOperations","deletePropertyByID",function(e,t,n){var r=i.getNode(e);s(!c.hasOwnProperty(t)),o.deleteValueForProperty(r,t,n)}),updateStylesByID:a.measure("ReactDOMIDOperations","updateStylesByID",function(e,t){var r=i.getNode(e);n.setValueForStyles(r,t)}),updateInnerHTMLByID:a.measure("ReactDOMIDOperations","updateInnerHTMLByID",function(e,t){var n=i.getNode(e);u(n,t)}),updateTextContentByID:a.measure("ReactDOMIDOperations","updateTextContentByID",function(e,t){var n=i.getNode(e);r.updateTextContent(n,t)}),dangerouslyReplaceNodeWithMarkupByID:a.measure("ReactDOMIDOperations","dangerouslyReplaceNodeWithMarkupByID",function(e,t){var n=i.getNode(e);r.dangerouslyReplaceNodeWithMarkup(n,t)}),dangerouslyProcessChildrenUpdates:a.measure("ReactDOMIDOperations","dangerouslyProcessChildrenUpdates",function(e,t){for(var n=0;n<e.length;n++)e[n].parentNode=i.getNode(e[n].parentID);r.processUpdates(e,t)})};t.exports=l},{"./CSSPropertyOperations":4,"./DOMChildrenOperations":9,"./DOMPropertyOperations":11,"./ReactMount":59,"./ReactPerf":63,"./invariant":118,"./setInnerHTML":134}],41:[function(e,t){"use strict";var n=e("./EventConstants"),r=e("./LocalEventTrapMixin"),o=e("./ReactBrowserComponentMixin"),i=e("./ReactCompositeComponent"),a=e("./ReactDOM"),s=a.img,u=i.createClass({displayName:"ReactDOMImg",tagName:"IMG",mixins:[o,r],render:function(){return s(this.props)},componentDidMount:function(){this.trapBubbledEvent(n.topLevelTypes.topLoad,"load"),this.trapBubbledEvent(n.topLevelTypes.topError,"error")}});t.exports=u},{"./EventConstants":15,"./LocalEventTrapMixin":24,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36}],42:[function(e,t){"use strict";var n=e("./AutoFocusMixin"),r=e("./DOMPropertyOperations"),o=e("./LinkedValueUtils"),i=e("./ReactBrowserComponentMixin"),a=e("./ReactCompositeComponent"),s=e("./ReactDOM"),u=e("./ReactMount"),c=e("./invariant"),l=e("./merge"),p=s.input,d={},f=a.createClass({displayName:"ReactDOMInput",mixins:[n,o.Mixin,i],getInitialState:function(){var e=this.props.defaultValue;return{checked:this.props.defaultChecked||!1,value:null!=e?e:null}},shouldComponentUpdate:function(){return!this._isChanging},render:function(){var e=l(this.props);e.defaultChecked=null,e.defaultValue=null;var t=o.getValue(this);e.value=null!=t?t:this.state.value;var n=o.getChecked(this);return e.checked=null!=n?n:this.state.checked,e.onChange=this._handleChange,p(e,this.props.children)},componentDidMount:function(){var e=u.getID(this.getDOMNode());d[e]=this},componentWillUnmount:function(){var e=this.getDOMNode(),t=u.getID(e);delete d[t]},componentDidUpdate:function(){var e=this.getDOMNode();null!=this.props.checked&&r.setValueForProperty(e,"checked",this.props.checked||!1);var t=o.getValue(this);null!=t&&r.setValueForProperty(e,"value",""+t)},_handleChange:function(e){var t,n=o.getOnChange(this);n&&(this._isChanging=!0,t=n.call(this,e),this._isChanging=!1),this.setState({checked:e.target.checked,value:e.target.value});var r=this.props.name;if("radio"===this.props.type&&null!=r){for(var i=this.getDOMNode(),a=i;a.parentNode;)a=a.parentNode;for(var s=a.querySelectorAll("input[name="+JSON.stringify(""+r)+'][type="radio"]'),l=0,p=s.length;p>l;l++){var f=s[l];if(f!==i&&f.form===i.form){var h=u.getID(f);c(h);var v=d[h];c(v),v.setState({checked:!1})}}}return t}});t.exports=f},{"./AutoFocusMixin":1,"./DOMPropertyOperations":11,"./LinkedValueUtils":23,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36,"./ReactMount":59,"./invariant":118,"./merge":128}],43:[function(e,t){"use strict";var n=e("./ReactBrowserComponentMixin"),r=e("./ReactCompositeComponent"),o=e("./ReactDOM"),i=(e("./warning"),o.option),a=r.createClass({displayName:"ReactDOMOption",mixins:[n],componentWillMount:function(){},render:function(){return i(this.props,this.props.children)}});t.exports=a},{"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36,"./warning":139}],44:[function(e,t){"use strict";function n(e,t){if(null!=e[t])if(e.multiple){if(!Array.isArray(e[t]))return new Error("The `"+t+"` prop supplied to <select> must be an array if `multiple` is true.")}else if(Array.isArray(e[t]))return new Error("The `"+t+"` prop supplied to <select> must be a scalar value if `multiple` is false.")}function r(e,t){var n,r,o,i=e.props.multiple,a=null!=t?t:e.state.value,s=e.getDOMNode().options;if(i)for(n={},r=0,o=a.length;o>r;++r)n[""+a[r]]=!0;else n=""+a;for(r=0,o=s.length;o>r;r++){var u=i?n.hasOwnProperty(s[r].value):s[r].value===n;u!==s[r].selected&&(s[r].selected=u)}}var o=e("./AutoFocusMixin"),i=e("./LinkedValueUtils"),a=e("./ReactBrowserComponentMixin"),s=e("./ReactCompositeComponent"),u=e("./ReactDOM"),c=e("./merge"),l=u.select,p=s.createClass({displayName:"ReactDOMSelect",mixins:[o,i.Mixin,a],propTypes:{defaultValue:n,value:n},getInitialState:function(){return{value:this.props.defaultValue||(this.props.multiple?[]:"")}},componentWillReceiveProps:function(e){!this.props.multiple&&e.multiple?this.setState({value:[this.state.value]}):this.props.multiple&&!e.multiple&&this.setState({value:this.state.value[0]})},shouldComponentUpdate:function(){return!this._isChanging},render:function(){var e=c(this.props);return e.onChange=this._handleChange,e.value=null,l(e,this.props.children)},componentDidMount:function(){r(this,i.getValue(this))},componentDidUpdate:function(e){var t=i.getValue(this),n=!!e.multiple,o=!!this.props.multiple;(null!=t||n!==o)&&r(this,t)},_handleChange:function(e){var t,n=i.getOnChange(this);n&&(this._isChanging=!0,t=n.call(this,e),this._isChanging=!1);var r;if(this.props.multiple){r=[];for(var o=e.target.options,a=0,s=o.length;s>a;a++)o[a].selected&&r.push(o[a].value)}else r=e.target.value;return this.setState({value:r}),t}});t.exports=p},{"./AutoFocusMixin":1,"./LinkedValueUtils":23,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36,"./merge":128}],45:[function(e,t){"use strict";function n(e,t,n,r){return e===n&&t===r}function r(e){var t=document.selection,n=t.createRange(),r=n.text.length,o=n.duplicate();o.moveToElementText(e),o.setEndPoint("EndToStart",n);var i=o.text.length,a=i+r;return{start:i,end:a}}function o(e){var t=window.getSelection();if(0===t.rangeCount)return null;var r=t.anchorNode,o=t.anchorOffset,i=t.focusNode,a=t.focusOffset,s=t.getRangeAt(0),u=n(t.anchorNode,t.anchorOffset,t.focusNode,t.focusOffset),c=u?0:s.toString().length,l=s.cloneRange();l.selectNodeContents(e),l.setEnd(s.startContainer,s.startOffset);var p=n(l.startContainer,l.startOffset,l.endContainer,l.endOffset),d=p?0:l.toString().length,f=d+c,h=document.createRange();h.setStart(r,o),h.setEnd(i,a);var v=h.collapsed;return h.detach(),{start:v?f:d,end:v?d:f}}function i(e,t){var n,r,o=document.selection.createRange().duplicate();"undefined"==typeof t.end?(n=t.start,r=n):t.start>t.end?(n=t.end,r=t.start):(n=t.start,r=t.end),o.moveToElementText(e),o.moveStart("character",n),o.setEndPoint("EndToStart",o),o.moveEnd("character",r-n),o.select()}function a(e,t){var n=window.getSelection(),r=e[c()].length,o=Math.min(t.start,r),i="undefined"==typeof t.end?o:Math.min(t.end,r);if(!n.extend&&o>i){var a=i;i=o,o=a}var s=u(e,o),l=u(e,i);if(s&&l){var p=document.createRange();p.setStart(s.node,s.offset),n.removeAllRanges(),o>i?(n.addRange(p),n.extend(l.node,l.offset)):(p.setEnd(l.node,l.offset),n.addRange(p)),p.detach()}}var s=e("./ExecutionEnvironment"),u=e("./getNodeForCharacterOffset"),c=e("./getTextContentAccessor"),l=s.canUseDOM&&document.selection,p={getOffsets:l?r:o,setOffsets:l?i:a};t.exports=p},{"./ExecutionEnvironment":21,"./getNodeForCharacterOffset":111,"./getTextContentAccessor":113}],46:[function(e,t){"use strict";var n=e("./AutoFocusMixin"),r=e("./DOMPropertyOperations"),o=e("./LinkedValueUtils"),i=e("./ReactBrowserComponentMixin"),a=e("./ReactCompositeComponent"),s=e("./ReactDOM"),u=e("./invariant"),c=e("./merge"),l=(e("./warning"),s.textarea),p=a.createClass({displayName:"ReactDOMTextarea",mixins:[n,o.Mixin,i],getInitialState:function(){var e=this.props.defaultValue,t=this.props.children;null!=t&&(u(null==e),Array.isArray(t)&&(u(t.length<=1),t=t[0]),e=""+t),null==e&&(e="");var n=o.getValue(this);return{initialValue:""+(null!=n?n:e)}},shouldComponentUpdate:function(){return!this._isChanging},render:function(){var e=c(this.props);return u(null==e.dangerouslySetInnerHTML),e.defaultValue=null,e.value=null,e.onChange=this._handleChange,l(e,this.state.initialValue)},componentDidUpdate:function(){var e=o.getValue(this);
-if(null!=e){var t=this.getDOMNode();r.setValueForProperty(t,"value",""+e)}},_handleChange:function(e){var t,n=o.getOnChange(this);return n&&(this._isChanging=!0,t=n.call(this,e),this._isChanging=!1),this.setState({value:e.target.value}),t}});t.exports=p},{"./AutoFocusMixin":1,"./DOMPropertyOperations":11,"./LinkedValueUtils":23,"./ReactBrowserComponentMixin":28,"./ReactCompositeComponent":33,"./ReactDOM":36,"./invariant":118,"./merge":128,"./warning":139}],47:[function(e,t){"use strict";function n(){this.reinitializeTransaction()}var r=e("./ReactUpdates"),o=e("./Transaction"),i=e("./emptyFunction"),a=e("./mixInto"),s={initialize:i,close:function(){p.isBatchingUpdates=!1}},u={initialize:i,close:r.flushBatchedUpdates.bind(r)},c=[u,s];a(n,o.Mixin),a(n,{getTransactionWrappers:function(){return c}});var l=new n,p={isBatchingUpdates:!1,batchedUpdates:function(e,t,n){var r=p.isBatchingUpdates;p.isBatchingUpdates=!0,r?e(t,n):l.perform(e,null,t,n)}};t.exports=p},{"./ReactUpdates":74,"./Transaction":90,"./emptyFunction":100,"./mixInto":131}],48:[function(e,t){"use strict";function n(){x.EventEmitter.injectReactEventListener(D),x.EventPluginHub.injectEventPluginOrder(s),x.EventPluginHub.injectInstanceHandle(b),x.EventPluginHub.injectMount(O),x.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:_,EnterLeaveEventPlugin:u,ChangeEventPlugin:o,CompositionEventPlugin:a,MobileSafariClickEventPlugin:p,SelectEventPlugin:P,BeforeInputEventPlugin:r}),x.DOM.injectComponentClasses({button:m,form:g,img:y,input:C,option:E,select:R,textarea:M,html:N(v.html),head:N(v.head),body:N(v.body)}),x.CompositeComponent.injectMixin(d),x.DOMProperty.injectDOMPropertyConfig(l),x.DOMProperty.injectDOMPropertyConfig(T),x.EmptyComponent.injectEmptyComponent(v.noscript),x.Updates.injectReconcileTransaction(f.ReactReconcileTransaction),x.Updates.injectBatchingStrategy(h),x.RootIndex.injectCreateReactRootIndex(c.canUseDOM?i.createReactRootIndex:I.createReactRootIndex),x.Component.injectEnvironment(f)}var r=e("./BeforeInputEventPlugin"),o=e("./ChangeEventPlugin"),i=e("./ClientReactRootIndex"),a=e("./CompositionEventPlugin"),s=e("./DefaultEventPluginOrder"),u=e("./EnterLeaveEventPlugin"),c=e("./ExecutionEnvironment"),l=e("./HTMLDOMPropertyConfig"),p=e("./MobileSafariClickEventPlugin"),d=e("./ReactBrowserComponentMixin"),f=e("./ReactComponentBrowserEnvironment"),h=e("./ReactDefaultBatchingStrategy"),v=e("./ReactDOM"),m=e("./ReactDOMButton"),g=e("./ReactDOMForm"),y=e("./ReactDOMImg"),C=e("./ReactDOMInput"),E=e("./ReactDOMOption"),R=e("./ReactDOMSelect"),M=e("./ReactDOMTextarea"),D=e("./ReactEventListener"),x=e("./ReactInjection"),b=e("./ReactInstanceHandles"),O=e("./ReactMount"),P=e("./SelectEventPlugin"),I=e("./ServerReactRootIndex"),_=e("./SimpleEventPlugin"),T=e("./SVGDOMPropertyConfig"),N=e("./createFullPageComponent");t.exports={inject:n}},{"./BeforeInputEventPlugin":2,"./ChangeEventPlugin":6,"./ClientReactRootIndex":7,"./CompositionEventPlugin":8,"./DefaultEventPluginOrder":13,"./EnterLeaveEventPlugin":14,"./ExecutionEnvironment":21,"./HTMLDOMPropertyConfig":22,"./MobileSafariClickEventPlugin":25,"./ReactBrowserComponentMixin":28,"./ReactComponentBrowserEnvironment":32,"./ReactDOM":36,"./ReactDOMButton":37,"./ReactDOMForm":39,"./ReactDOMImg":41,"./ReactDOMInput":42,"./ReactDOMOption":43,"./ReactDOMSelect":44,"./ReactDOMTextarea":46,"./ReactDefaultBatchingStrategy":47,"./ReactEventListener":54,"./ReactInjection":55,"./ReactInstanceHandles":57,"./ReactMount":59,"./SVGDOMPropertyConfig":75,"./SelectEventPlugin":76,"./ServerReactRootIndex":77,"./SimpleEventPlugin":78,"./createFullPageComponent":97}],49:[function(e,t){"use strict";function n(e,t){if("function"==typeof t)for(var n in t)if(t.hasOwnProperty(n)){var r=t[n];if("function"==typeof r){var o=r.bind(t);for(var i in r)r.hasOwnProperty(i)&&(o[i]=r[i]);e[n]=o}else e[n]=r}}var r=e("./ReactContext"),o=e("./ReactCurrentOwner"),i=e("./merge"),a=(e("./warning"),function(){});a.createFactory=function(e){var t=Object.create(a.prototype),s=function(e,n){null==e?e={}:"object"==typeof e&&(e=i(e));var a=arguments.length-1;if(1===a)e.children=n;else if(a>1){for(var s=Array(a),u=0;a>u;u++)s[u]=arguments[u+1];e.children=s}var c=Object.create(t);return c._owner=o.current,c._context=r.current,c.props=e,c};return s.prototype=t,s.type=e,t.type=e,n(s,e),t.constructor=s,s},a.cloneAndReplaceProps=function(e,t){var n=Object.create(e.constructor.prototype);return n._owner=e._owner,n._context=e._context,n.props=t,n},a.isValidFactory=function(e){return"function"==typeof e&&e.prototype instanceof a},a.isValidDescriptor=function(e){return e instanceof a},t.exports=a},{"./ReactContext":34,"./ReactCurrentOwner":35,"./merge":128,"./warning":139}],50:[function(e,t){"use strict";function n(){var e=p.current;return e&&e.constructor.displayName||void 0}function r(e,t){e._store.validated||null!=e.props.key||(e._store.validated=!0,i("react_key_warning",'Each child in an array should have a unique "key" prop.',e,t))}function o(e,t,n){m.test(e)&&i("react_numeric_key_warning","Child objects should have non-numeric keys so ordering is preserved.",t,n)}function i(e,t,r,o){var i=n(),a=o.displayName,s=i||a,u=f[e];if(!u.hasOwnProperty(s)){u[s]=!0,t+=i?" Check the render method of "+i+".":" Check the renderComponent call using <"+a+">.";var c=null;r._owner&&r._owner!==p.current&&(c=r._owner.constructor.displayName,t+=" It was passed a child from "+c+"."),t+=" See http://fb.me/react-warning-keys for more information.",d(e,{component:s,componentOwner:c}),console.warn(t)}}function a(){var e=n()||"";h.hasOwnProperty(e)||(h[e]=!0,d("react_object_map_children"))}function s(e,t){if(Array.isArray(e))for(var n=0;n<e.length;n++){var i=e[n];c.isValidDescriptor(i)&&r(i,t)}else if(c.isValidDescriptor(e))e._store.validated=!0;else if(e&&"object"==typeof e){a();for(var s in e)o(s,e[s],t)}}function u(e,t,n,r){for(var o in t)if(t.hasOwnProperty(o)){var i;try{i=t[o](n,o,e,r)}catch(a){i=a}i instanceof Error&&!(i.message in v)&&(v[i.message]=!0,d("react_failed_descriptor_type_check",{message:i.message}))}}var c=e("./ReactDescriptor"),l=e("./ReactPropTypeLocations"),p=e("./ReactCurrentOwner"),d=e("./monitorCodeUse"),f={react_key_warning:{},react_numeric_key_warning:{}},h={},v={},m=/^\d+$/,g={createFactory:function(e,t,n){var r=function(){for(var r=e.apply(this,arguments),o=1;o<arguments.length;o++)s(arguments[o],r.type);var i=r.type.displayName;return t&&u(i,t,r.props,l.prop),n&&u(i,n,r._context,l.context),r};r.prototype=e.prototype,r.type=e.type;for(var o in e)e.hasOwnProperty(o)&&(r[o]=e[o]);return r}};t.exports=g},{"./ReactCurrentOwner":35,"./ReactDescriptor":49,"./ReactPropTypeLocations":66,"./monitorCodeUse":132}],51:[function(e,t){"use strict";function n(){return s(a),a()}function r(e){u[e]=!0}function o(e){delete u[e]}function i(e){return u[e]}var a,s=e("./invariant"),u={},c={injectEmptyComponent:function(e){a=e}},l={deregisterNullComponentID:o,getEmptyComponent:n,injection:c,isNullComponentID:i,registerNullComponentID:r};t.exports=l},{"./invariant":118}],52:[function(e,t){"use strict";var n={guard:function(e){return e}};t.exports=n},{}],53:[function(e,t){"use strict";function n(e){r.enqueueEvents(e),r.processEventQueue()}var r=e("./EventPluginHub"),o={handleTopLevel:function(e,t,o,i){var a=r.extractEvents(e,t,o,i);n(a)}};t.exports=o},{"./EventPluginHub":17}],54:[function(e,t){"use strict";function n(e){var t=l.getID(e),n=c.getReactRootIDFromNodeID(t),r=l.findReactContainerForID(n),o=l.getFirstReactDOM(r);return o}function r(e,t){this.topLevelType=e,this.nativeEvent=t,this.ancestors=[]}function o(e){for(var t=l.getFirstReactDOM(d(e.nativeEvent))||window,r=t;r;)e.ancestors.push(r),r=n(r);for(var o=0,i=e.ancestors.length;i>o;o++){t=e.ancestors[o];var a=l.getID(t)||"";v._handleTopLevel(e.topLevelType,t,a,e.nativeEvent)}}function i(e){var t=f(window);e(t)}var a=e("./EventListener"),s=e("./ExecutionEnvironment"),u=e("./PooledClass"),c=e("./ReactInstanceHandles"),l=e("./ReactMount"),p=e("./ReactUpdates"),d=e("./getEventTarget"),f=e("./getUnboundedScrollPosition"),h=e("./mixInto");h(r,{destructor:function(){this.topLevelType=null,this.nativeEvent=null,this.ancestors.length=0}}),u.addPoolingTo(r,u.twoArgumentPooler);var v={_enabled:!0,_handleTopLevel:null,WINDOW_HANDLE:s.canUseDOM?window:null,setHandleTopLevel:function(e){v._handleTopLevel=e},setEnabled:function(e){v._enabled=!!e},isEnabled:function(){return v._enabled},trapBubbledEvent:function(e,t,n){var r=n;return r?a.listen(r,t,v.dispatchEvent.bind(null,e)):void 0},trapCapturedEvent:function(e,t,n){var r=n;return r?a.capture(r,t,v.dispatchEvent.bind(null,e)):void 0},monitorScrollValue:function(e){var t=i.bind(null,e);a.listen(window,"scroll",t),a.listen(window,"resize",t)},dispatchEvent:function(e,t){if(v._enabled){var n=r.getPooled(e,t);try{p.batchedUpdates(o,n)}finally{r.release(n)}}}};t.exports=v},{"./EventListener":16,"./ExecutionEnvironment":21,"./PooledClass":26,"./ReactInstanceHandles":57,"./ReactMount":59,"./ReactUpdates":74,"./getEventTarget":109,"./getUnboundedScrollPosition":114,"./mixInto":131}],55:[function(e,t){"use strict";var n=e("./DOMProperty"),r=e("./EventPluginHub"),o=e("./ReactComponent"),i=e("./ReactCompositeComponent"),a=e("./ReactDOM"),s=e("./ReactEmptyComponent"),u=e("./ReactBrowserEventEmitter"),c=e("./ReactPerf"),l=e("./ReactRootIndex"),p=e("./ReactUpdates"),d={Component:o.injection,CompositeComponent:i.injection,DOMProperty:n.injection,EmptyComponent:s.injection,EventPluginHub:r.injection,DOM:a.injection,EventEmitter:u.injection,Perf:c.injection,RootIndex:l.injection,Updates:p.injection};t.exports=d},{"./DOMProperty":10,"./EventPluginHub":17,"./ReactBrowserEventEmitter":29,"./ReactComponent":31,"./ReactCompositeComponent":33,"./ReactDOM":36,"./ReactEmptyComponent":51,"./ReactPerf":63,"./ReactRootIndex":70,"./ReactUpdates":74}],56:[function(e,t){"use strict";function n(e){return o(document.documentElement,e)}var r=e("./ReactDOMSelection"),o=e("./containsNode"),i=e("./focusNode"),a=e("./getActiveElement"),s={hasSelectionCapabilities:function(e){return e&&("INPUT"===e.nodeName&&"text"===e.type||"TEXTAREA"===e.nodeName||"true"===e.contentEditable)},getSelectionInformation:function(){var e=a();return{focusedElem:e,selectionRange:s.hasSelectionCapabilities(e)?s.getSelection(e):null}},restoreSelection:function(e){var t=a(),r=e.focusedElem,o=e.selectionRange;t!==r&&n(r)&&(s.hasSelectionCapabilities(r)&&s.setSelection(r,o),i(r))},getSelection:function(e){var t;if("selectionStart"in e)t={start:e.selectionStart,end:e.selectionEnd};else if(document.selection&&"INPUT"===e.nodeName){var n=document.selection.createRange();n.parentElement()===e&&(t={start:-n.moveStart("character",-e.value.length),end:-n.moveEnd("character",-e.value.length)})}else t=r.getOffsets(e);return t||{start:0,end:0}},setSelection:function(e,t){var n=t.start,o=t.end;if("undefined"==typeof o&&(o=n),"selectionStart"in e)e.selectionStart=n,e.selectionEnd=Math.min(o,e.value.length);else if(document.selection&&"INPUT"===e.nodeName){var i=e.createTextRange();i.collapse(!0),i.moveStart("character",n),i.moveEnd("character",o-n),i.select()}else r.setOffsets(e,t)}};t.exports=s},{"./ReactDOMSelection":45,"./containsNode":94,"./focusNode":104,"./getActiveElement":106}],57:[function(e,t){"use strict";function n(e){return d+e.toString(36)}function r(e,t){return e.charAt(t)===d||t===e.length}function o(e){return""===e||e.charAt(0)===d&&e.charAt(e.length-1)!==d}function i(e,t){return 0===t.indexOf(e)&&r(t,e.length)}function a(e){return e?e.substr(0,e.lastIndexOf(d)):""}function s(e,t){if(p(o(e)&&o(t)),p(i(e,t)),e===t)return e;for(var n=e.length+f,a=n;a<t.length&&!r(t,a);a++);return t.substr(0,a)}function u(e,t){var n=Math.min(e.length,t.length);if(0===n)return"";for(var i=0,a=0;n>=a;a++)if(r(e,a)&&r(t,a))i=a;else if(e.charAt(a)!==t.charAt(a))break;var s=e.substr(0,i);return p(o(s)),s}function c(e,t,n,r,o,u){e=e||"",t=t||"",p(e!==t);var c=i(t,e);p(c||i(e,t));for(var l=0,d=c?a:s,f=e;;f=d(f,t)){var v;if(o&&f===e||u&&f===t||(v=n(f,c,r)),v===!1||f===t)break;p(l++<h)}}var l=e("./ReactRootIndex"),p=e("./invariant"),d=".",f=d.length,h=100,v={createReactRootID:function(){return n(l.createReactRootIndex())},createReactID:function(e,t){return e+t},getReactRootIDFromNodeID:function(e){if(e&&e.charAt(0)===d&&e.length>1){var t=e.indexOf(d,1);return t>-1?e.substr(0,t):e}return null},traverseEnterLeave:function(e,t,n,r,o){var i=u(e,t);i!==e&&c(e,i,n,r,!1,!0),i!==t&&c(i,t,n,o,!0,!1)},traverseTwoPhase:function(e,t,n){e&&(c("",e,t,n,!0,!1),c(e,"",t,n,!1,!0))},traverseAncestors:function(e,t,n){c("",e,t,n,!0,!1)},_getFirstCommonAncestorID:u,_getNextDescendantID:s,isAncestorIDOf:i,SEPARATOR:d};t.exports=v},{"./ReactRootIndex":70,"./invariant":118}],58:[function(e,t){"use strict";var n=e("./adler32"),r={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(e){var t=n(e);return e.replace(">"," "+r.CHECKSUM_ATTR_NAME+'="'+t+'">')},canReuseMarkup:function(e,t){var o=t.getAttribute(r.CHECKSUM_ATTR_NAME);o=o&&parseInt(o,10);var i=n(e);return i===o}};t.exports=r},{"./adler32":93}],59:[function(e,t){"use strict";function n(e){var t=g(e);return t&&T.getID(t)}function r(e){var t=o(e);if(t)if(D.hasOwnProperty(t)){var n=D[t];n!==e&&(C(!s(n,t)),D[t]=e)}else D[t]=e;return t}function o(e){return e&&e.getAttribute&&e.getAttribute(M)||""}function i(e,t){var n=o(e);n!==t&&delete D[n],e.setAttribute(M,t),D[t]=e}function a(e){return D.hasOwnProperty(e)&&s(D[e],e)||(D[e]=T.findReactNodeByID(e)),D[e]}function s(e,t){if(e){C(o(e)===t);var n=T.findReactContainerForID(t);if(n&&m(n,e))return!0}return!1}function u(e){delete D[e]}function c(e){var t=D[e];return t&&s(t,e)?void(_=t):!1}function l(e){_=null,h.traverseAncestors(e,c);var t=_;return _=null,t}var p=e("./DOMProperty"),d=e("./ReactBrowserEventEmitter"),f=(e("./ReactCurrentOwner"),e("./ReactDescriptor")),h=e("./ReactInstanceHandles"),v=e("./ReactPerf"),m=e("./containsNode"),g=e("./getReactRootElementInContainer"),y=e("./instantiateReactComponent"),C=e("./invariant"),E=e("./shouldUpdateReactComponent"),R=(e("./warning"),h.SEPARATOR),M=p.ID_ATTRIBUTE_NAME,D={},x=1,b=9,O={},P={},I=[],_=null,T={_instancesByReactRootID:O,scrollMonitor:function(e,t){t()},_updateRootComponent:function(e,t,n,r){var o=t.props;return T.scrollMonitor(n,function(){e.replaceProps(o,r)}),e},_registerComponent:function(e,t){C(t&&(t.nodeType===x||t.nodeType===b)),d.ensureScrollValueMonitoring();var n=T.registerContainer(t);return O[n]=e,n},_renderNewRootComponent:v.measure("ReactMount","_renderNewRootComponent",function(e,t,n){var r=y(e),o=T._registerComponent(r,t);return r.mountComponentIntoNode(o,t,n),r}),renderComponent:function(e,t,r){C(f.isValidDescriptor(e));var o=O[n(t)];if(o){var i=o._descriptor;if(E(i,e))return T._updateRootComponent(o,e,t,r);T.unmountComponentAtNode(t)}var a=g(t),s=a&&T.isRenderedByReact(a),u=s&&!o,c=T._renderNewRootComponent(e,t,u);return r&&r.call(c),c},constructAndRenderComponent:function(e,t,n){return T.renderComponent(e(t),n)},constructAndRenderComponentByID:function(e,t,n){var r=document.getElementById(n);return C(r),T.constructAndRenderComponent(e,t,r)},registerContainer:function(e){var t=n(e);return t&&(t=h.getReactRootIDFromNodeID(t)),t||(t=h.createReactRootID()),P[t]=e,t},unmountComponentAtNode:function(e){var t=n(e),r=O[t];return r?(T.unmountComponentFromNode(r,e),delete O[t],delete P[t],!0):!1},unmountComponentFromNode:function(e,t){for(e.unmountComponent(),t.nodeType===b&&(t=t.documentElement);t.lastChild;)t.removeChild(t.lastChild)},findReactContainerForID:function(e){var t=h.getReactRootIDFromNodeID(e),n=P[t];return n},findReactNodeByID:function(e){var t=T.findReactContainerForID(e);return T.findComponentRoot(t,e)},isRenderedByReact:function(e){if(1!==e.nodeType)return!1;var t=T.getID(e);return t?t.charAt(0)===R:!1},getFirstReactDOM:function(e){for(var t=e;t&&t.parentNode!==t;){if(T.isRenderedByReact(t))return t;t=t.parentNode}return null},findComponentRoot:function(e,t){var n=I,r=0,o=l(t)||e;for(n[0]=o.firstChild,n.length=1;r<n.length;){for(var i,a=n[r++];a;){var s=T.getID(a);s?t===s?i=a:h.isAncestorIDOf(s,t)&&(n.length=r=0,n.push(a.firstChild)):n.push(a.firstChild),a=a.nextSibling}if(i)return n.length=0,i}n.length=0,C(!1)},getReactRootID:n,getID:r,setID:i,getNode:a,purgeID:u};t.exports=T},{"./DOMProperty":10,"./ReactBrowserEventEmitter":29,"./ReactCurrentOwner":35,"./ReactDescriptor":49,"./ReactInstanceHandles":57,"./ReactPerf":63,"./containsNode":94,"./getReactRootElementInContainer":112,"./instantiateReactComponent":117,"./invariant":118,"./shouldUpdateReactComponent":136,"./warning":139}],60:[function(e,t){"use strict";function n(e,t,n){h.push({parentID:e,parentNode:null,type:c.INSERT_MARKUP,markupIndex:v.push(t)-1,textContent:null,fromIndex:null,toIndex:n})}function r(e,t,n){h.push({parentID:e,parentNode:null,type:c.MOVE_EXISTING,markupIndex:null,textContent:null,fromIndex:t,toIndex:n})}function o(e,t){h.push({parentID:e,parentNode:null,type:c.REMOVE_NODE,markupIndex:null,textContent:null,fromIndex:t,toIndex:null})}function i(e,t){h.push({parentID:e,parentNode:null,type:c.TEXT_CONTENT,markupIndex:null,textContent:t,fromIndex:null,toIndex:null})}function a(){h.length&&(u.BackendIDOperations.dangerouslyProcessChildrenUpdates(h,v),s())}function s(){h.length=0,v.length=0}var u=e("./ReactComponent"),c=e("./ReactMultiChildUpdateTypes"),l=e("./flattenChildren"),p=e("./instantiateReactComponent"),d=e("./shouldUpdateReactComponent"),f=0,h=[],v=[],m={Mixin:{mountChildren:function(e,t){var n=l(e),r=[],o=0;this._renderedChildren=n;for(var i in n){var a=n[i];if(n.hasOwnProperty(i)){var s=p(a);n[i]=s;var u=this._rootNodeID+i,c=s.mountComponent(u,t,this._mountDepth+1);s._mountIndex=o,r.push(c),o++}}return r},updateTextContent:function(e){f++;var t=!0;try{var n=this._renderedChildren;for(var r in n)n.hasOwnProperty(r)&&this._unmountChildByName(n[r],r);this.setTextContent(e),t=!1}finally{f--,f||(t?s():a())}},updateChildren:function(e,t){f++;var n=!0;try{this._updateChildren(e,t),n=!1}finally{f--,f||(n?s():a())}},_updateChildren:function(e,t){var n=l(e),r=this._renderedChildren;if(n||r){var o,i=0,a=0;for(o in n)if(n.hasOwnProperty(o)){var s=r&&r[o],u=s&&s._descriptor,c=n[o];if(d(u,c))this.moveChild(s,a,i),i=Math.max(s._mountIndex,i),s.receiveComponent(c,t),s._mountIndex=a;else{s&&(i=Math.max(s._mountIndex,i),this._unmountChildByName(s,o));var f=p(c);this._mountChildByNameAtIndex(f,o,a,t)}a++}for(o in r)!r.hasOwnProperty(o)||n&&n[o]||this._unmountChildByName(r[o],o)}},unmountChildren:function(){var e=this._renderedChildren;for(var t in e){var n=e[t];n.unmountComponent&&n.unmountComponent()}this._renderedChildren=null},moveChild:function(e,t,n){e._mountIndex<n&&r(this._rootNodeID,e._mountIndex,t)},createChild:function(e,t){n(this._rootNodeID,t,e._mountIndex)},removeChild:function(e){o(this._rootNodeID,e._mountIndex)},setTextContent:function(e){i(this._rootNodeID,e)},_mountChildByNameAtIndex:function(e,t,n,r){var o=this._rootNodeID+t,i=e.mountComponent(o,r,this._mountDepth+1);e._mountIndex=n,this.createChild(e,i),this._renderedChildren=this._renderedChildren||{},this._renderedChildren[t]=e},_unmountChildByName:function(e,t){this.removeChild(e),e._mountIndex=null,e.unmountComponent(),delete this._renderedChildren[t]}}};t.exports=m},{"./ReactComponent":31,"./ReactMultiChildUpdateTypes":61,"./flattenChildren":103,"./instantiateReactComponent":117,"./shouldUpdateReactComponent":136}],61:[function(e,t){"use strict";var n=e("./keyMirror"),r=n({INSERT_MARKUP:null,MOVE_EXISTING:null,REMOVE_NODE:null,TEXT_CONTENT:null});t.exports=r},{"./keyMirror":124}],62:[function(e,t){"use strict";var n=e("./emptyObject"),r=e("./invariant"),o={isValidOwner:function(e){return!(!e||"function"!=typeof e.attachRef||"function"!=typeof e.detachRef)},addComponentAsRefTo:function(e,t,n){r(o.isValidOwner(n)),n.attachRef(t,e)},removeComponentAsRefFrom:function(e,t,n){r(o.isValidOwner(n)),n.refs[t]===e&&n.detachRef(t)},Mixin:{construct:function(){this.refs=n},attachRef:function(e,t){r(t.isOwnedBy(this));var o=this.refs===n?this.refs={}:this.refs;o[e]=t},detachRef:function(e){delete this.refs[e]}}};t.exports=o},{"./emptyObject":101,"./invariant":118}],63:[function(e,t){"use strict";function n(e,t,n){return n}var r={enableMeasure:!1,storedMeasure:n,measure:function(e,t,n){return n},injection:{injectMeasure:function(e){r.storedMeasure=e}}};t.exports=r},{}],64:[function(e,t){"use strict";function n(e){return function(t,n,r){t[n]=t.hasOwnProperty(n)?e(t[n],r):r}}function r(e,t){for(var n in t)if(t.hasOwnProperty(n)){var r=c[n];r&&c.hasOwnProperty(n)?r(e,n,t[n]):e.hasOwnProperty(n)||(e[n]=t[n])}return e}var o=e("./emptyFunction"),i=e("./invariant"),a=e("./joinClasses"),s=e("./merge"),u=n(function(e,t){return s(t,e)}),c={children:o,className:n(a),key:o,ref:o,style:u},l={TransferStrategies:c,mergeProps:function(e,t){return r(s(e),t)},Mixin:{transferPropsTo:function(e){return i(e._owner===this),r(e.props,this.props),e}}};t.exports=l},{"./emptyFunction":100,"./invariant":118,"./joinClasses":123,"./merge":128}],65:[function(e,t){"use strict";var n={};t.exports=n},{}],66:[function(e,t){"use strict";var n=e("./keyMirror"),r=n({prop:null,context:null,childContext:null});t.exports=r},{"./keyMirror":124}],67:[function(e,t){"use strict";function n(e){function t(t,n,r,o,i){if(o=o||C,null!=n[r])return e(n,r,o,i);var a=g[i];return t?new Error("Required "+a+" `"+r+"` was not specified in "+("`"+o+"`.")):void 0}var n=t.bind(null,!1);return n.isRequired=t.bind(null,!0),n}function r(e){function t(t,n,r,o){var i=t[n],a=h(i);if(a!==e){var s=g[o],u=v(i);return new Error("Invalid "+s+" `"+n+"` of type `"+u+"` "+("supplied to `"+r+"`, expected `"+e+"`."))}}return n(t)}function o(){return n(y.thatReturns())}function i(e){function t(t,n,r,o){var i=t[n];if(!Array.isArray(i)){var a=g[o],s=h(i);return new Error("Invalid "+a+" `"+n+"` of type "+("`"+s+"` supplied to `"+r+"`, expected an array."))}for(var u=0;u<i.length;u++){var c=e(i,u,r,o);if(c instanceof Error)return c}}return n(t)}function a(){function e(e,t,n,r){if(!m.isValidDescriptor(e[t])){var o=g[r];return new Error("Invalid "+o+" `"+t+"` supplied to "+("`"+n+"`, expected a React component."))}}return n(e)}function s(e){function t(t,n,r,o){if(!(t[n]instanceof e)){var i=g[o],a=e.name||C;return new Error("Invalid "+i+" `"+n+"` supplied to "+("`"+r+"`, expected instance of `"+a+"`."))}}return n(t)}function u(e){function t(t,n,r,o){for(var i=t[n],a=0;a<e.length;a++)if(i===e[a])return;var s=g[o],u=JSON.stringify(e);return new Error("Invalid "+s+" `"+n+"` of value `"+i+"` "+("supplied to `"+r+"`, expected one of "+u+"."))}return n(t)}function c(e){function t(t,n,r,o){var i=t[n],a=h(i);if("object"!==a){var s=g[o];return new Error("Invalid "+s+" `"+n+"` of type "+("`"+a+"` supplied to `"+r+"`, expected an object."))}for(var u in i)if(i.hasOwnProperty(u)){var c=e(i,u,r,o);if(c instanceof Error)return c}}return n(t)}function l(e){function t(t,n,r,o){for(var i=0;i<e.length;i++){var a=e[i];if(null==a(t,n,r,o))return}var s=g[o];return new Error("Invalid "+s+" `"+n+"` supplied to "+("`"+r+"`."))}return n(t)}function p(){function e(e,t,n,r){if(!f(e[t])){var o=g[r];return new Error("Invalid "+o+" `"+t+"` supplied to "+("`"+n+"`, expected a renderable prop."))}}return n(e)}function d(e){function t(t,n,r,o){var i=t[n],a=h(i);if("object"!==a){var s=g[o];return new Error("Invalid "+s+" `"+n+"` of type `"+a+"` "+("supplied to `"+r+"`, expected `object`."))}for(var u in e){var c=e[u];if(c){var l=c(i,u,r,o);if(l)return l}}}return n(t,"expected `object`")}function f(e){switch(typeof e){case"number":case"string":return!0;case"boolean":return!e;case"object":if(Array.isArray(e))return e.every(f);if(m.isValidDescriptor(e))return!0;for(var t in e)if(!f(e[t]))return!1;return!0;default:return!1}}function h(e){var t=typeof e;return Array.isArray(e)?"array":e instanceof RegExp?"object":t}function v(e){var t=h(e);if("object"===t){if(e instanceof Date)return"date";if(e instanceof RegExp)return"regexp"}return t}var m=e("./ReactDescriptor"),g=e("./ReactPropTypeLocationNames"),y=e("./emptyFunction"),C="<<anonymous>>",E={array:r("array"),bool:r("boolean"),func:r("function"),number:r("number"),object:r("object"),string:r("string"),any:o(),arrayOf:i,component:a(),instanceOf:s,objectOf:c,oneOf:u,oneOfType:l,renderable:p(),shape:d};t.exports=E},{"./ReactDescriptor":49,"./ReactPropTypeLocationNames":65,"./emptyFunction":100}],68:[function(e,t){"use strict";function n(){this.listenersToPut=[]}var r=e("./PooledClass"),o=e("./ReactBrowserEventEmitter"),i=e("./mixInto");i(n,{enqueuePutListener:function(e,t,n){this.listenersToPut.push({rootNodeID:e,propKey:t,propValue:n})},putListeners:function(){for(var e=0;e<this.listenersToPut.length;e++){var t=this.listenersToPut[e];o.putListener(t.rootNodeID,t.propKey,t.propValue)}},reset:function(){this.listenersToPut.length=0},destructor:function(){this.reset()}}),r.addPoolingTo(n),t.exports=n},{"./PooledClass":26,"./ReactBrowserEventEmitter":29,"./mixInto":131}],69:[function(e,t){"use strict";function n(){this.reinitializeTransaction(),this.renderToStaticMarkup=!1,this.reactMountReady=r.getPooled(null),this.putListenerQueue=s.getPooled()}var r=e("./CallbackQueue"),o=e("./PooledClass"),i=e("./ReactBrowserEventEmitter"),a=e("./ReactInputSelection"),s=e("./ReactPutListenerQueue"),u=e("./Transaction"),c=e("./mixInto"),l={initialize:a.getSelectionInformation,close:a.restoreSelection},p={initialize:function(){var e=i.isEnabled();return i.setEnabled(!1),e},close:function(e){i.setEnabled(e)}},d={initialize:function(){this.reactMountReady.reset()},close:function(){this.reactMountReady.notifyAll()}},f={initialize:function(){this.putListenerQueue.reset()},close:function(){this.putListenerQueue.putListeners()}},h=[f,l,p,d],v={getTransactionWrappers:function(){return h},getReactMountReady:function(){return this.reactMountReady},getPutListenerQueue:function(){return this.putListenerQueue},destructor:function(){r.release(this.reactMountReady),this.reactMountReady=null,s.release(this.putListenerQueue),this.putListenerQueue=null}};c(n,u.Mixin),c(n,v),o.addPoolingTo(n),t.exports=n},{"./CallbackQueue":5,"./PooledClass":26,"./ReactBrowserEventEmitter":29,"./ReactInputSelection":56,"./ReactPutListenerQueue":68,"./Transaction":90,"./mixInto":131}],70:[function(e,t){"use strict";var n={injectCreateReactRootIndex:function(e){r.createReactRootIndex=e}},r={createReactRootIndex:null,injection:n};t.exports=r},{}],71:[function(e,t){"use strict";function n(e){c(o.isValidDescriptor(e)),c(!(2===arguments.length&&"function"==typeof arguments[1]));var t;try{var n=i.createReactRootID();return t=s.getPooled(!1),t.perform(function(){var r=u(e),o=r.mountComponent(n,t,0);return a.addChecksumToMarkup(o)},null)}finally{s.release(t)}}function r(e){c(o.isValidDescriptor(e));var t;try{var n=i.createReactRootID();return t=s.getPooled(!0),t.perform(function(){var r=u(e);return r.mountComponent(n,t,0)},null)}finally{s.release(t)}}var o=e("./ReactDescriptor"),i=e("./ReactInstanceHandles"),a=e("./ReactMarkupChecksum"),s=e("./ReactServerRenderingTransaction"),u=e("./instantiateReactComponent"),c=e("./invariant");t.exports={renderComponentToString:n,renderComponentToStaticMarkup:r}},{"./ReactDescriptor":49,"./ReactInstanceHandles":57,"./ReactMarkupChecksum":58,"./ReactServerRenderingTransaction":72,"./instantiateReactComponent":117,"./invariant":118}],72:[function(e,t){"use strict";function n(e){this.reinitializeTransaction(),this.renderToStaticMarkup=e,this.reactMountReady=o.getPooled(null),this.putListenerQueue=i.getPooled()}var r=e("./PooledClass"),o=e("./CallbackQueue"),i=e("./ReactPutListenerQueue"),a=e("./Transaction"),s=e("./emptyFunction"),u=e("./mixInto"),c={initialize:function(){this.reactMountReady.reset()},close:s},l={initialize:function(){this.putListenerQueue.reset()},close:s},p=[l,c],d={getTransactionWrappers:function(){return p},getReactMountReady:function(){return this.reactMountReady},getPutListenerQueue:function(){return this.putListenerQueue},destructor:function(){o.release(this.reactMountReady),this.reactMountReady=null,i.release(this.putListenerQueue),this.putListenerQueue=null}};u(n,a.Mixin),u(n,d),r.addPoolingTo(n),t.exports=n},{"./CallbackQueue":5,"./PooledClass":26,"./ReactPutListenerQueue":68,"./Transaction":90,"./emptyFunction":100,"./mixInto":131}],73:[function(e,t){"use strict";var n=e("./DOMPropertyOperations"),r=e("./ReactBrowserComponentMixin"),o=e("./ReactComponent"),i=e("./ReactDescriptor"),a=e("./escapeTextForBrowser"),s=e("./mixInto"),u=function(e){this.construct(e)};s(u,o.Mixin),s(u,r),s(u,{mountComponent:function(e,t,r){o.Mixin.mountComponent.call(this,e,t,r);var i=a(this.props);return t.renderToStaticMarkup?i:"<span "+n.createMarkupForID(e)+">"+i+"</span>"},receiveComponent:function(e){var t=e.props;t!==this.props&&(this.props=t,o.BackendIDOperations.updateTextContentByID(this._rootNodeID,t))}}),t.exports=i.createFactory(u)},{"./DOMPropertyOperations":11,"./ReactBrowserComponentMixin":28,"./ReactComponent":31,"./ReactDescriptor":49,"./escapeTextForBrowser":102,"./mixInto":131}],74:[function(e,t){"use strict";function n(){d(R.ReactReconcileTransaction&&v)}function r(){this.reinitializeTransaction(),this.dirtyComponentsLength=null,this.callbackQueue=u.getPooled(null),this.reconcileTransaction=R.ReactReconcileTransaction.getPooled()}function o(e,t,r){n(),v.batchedUpdates(e,t,r)}function i(e,t){return e._mountDepth-t._mountDepth}function a(e){var t=e.dirtyComponentsLength;d(t===h.length),h.sort(i);for(var n=0;t>n;n++){var r=h[n];if(r.isMounted()){var o=r._pendingCallbacks;if(r._pendingCallbacks=null,r.performUpdateIfNecessary(e.reconcileTransaction),o)for(var a=0;a<o.length;a++)e.callbackQueue.enqueue(o[a],r)}}}function s(e,t){return d(!t||"function"==typeof t),n(),v.isBatchingUpdates?(h.push(e),void(t&&(e._pendingCallbacks?e._pendingCallbacks.push(t):e._pendingCallbacks=[t]))):void v.batchedUpdates(s,e,t)}var u=e("./CallbackQueue"),c=e("./PooledClass"),l=(e("./ReactCurrentOwner"),e("./ReactPerf")),p=e("./Transaction"),d=e("./invariant"),f=e("./mixInto"),h=(e("./warning"),[]),v=null,m={initialize:function(){this.dirtyComponentsLength=h.length},close:function(){this.dirtyComponentsLength!==h.length?(h.splice(0,this.dirtyComponentsLength),C()):h.length=0}},g={initialize:function(){this.callbackQueue.reset()},close:function(){this.callbackQueue.notifyAll()}},y=[m,g];f(r,p.Mixin),f(r,{getTransactionWrappers:function(){return y},destructor:function(){this.dirtyComponentsLength=null,u.release(this.callbackQueue),this.callbackQueue=null,R.ReactReconcileTransaction.release(this.reconcileTransaction),this.reconcileTransaction=null},perform:function(e,t,n){return p.Mixin.perform.call(this,this.reconcileTransaction.perform,this.reconcileTransaction,e,t,n)}}),c.addPoolingTo(r);var C=l.measure("ReactUpdates","flushBatchedUpdates",function(){for(;h.length;){var e=r.getPooled();e.perform(a,null,e),r.release(e)}}),E={injectReconcileTransaction:function(e){d(e),R.ReactReconcileTransaction=e},injectBatchingStrategy:function(e){d(e),d("function"==typeof e.batchedUpdates),d("boolean"==typeof e.isBatchingUpdates),v=e}},R={ReactReconcileTransaction:null,batchedUpdates:o,enqueueUpdate:s,flushBatchedUpdates:C,injection:E};t.exports=R},{"./CallbackQueue":5,"./PooledClass":26,"./ReactCurrentOwner":35,"./ReactPerf":63,"./Transaction":90,"./invariant":118,"./mixInto":131,"./warning":139}],75:[function(e,t){"use strict";var n=e("./DOMProperty"),r=n.injection.MUST_USE_ATTRIBUTE,o={Properties:{cx:r,cy:r,d:r,dx:r,dy:r,fill:r,fillOpacity:r,fontFamily:r,fontSize:r,fx:r,fy:r,gradientTransform:r,gradientUnits:r,markerEnd:r,markerMid:r,markerStart:r,offset:r,opacity:r,patternContentUnits:r,patternUnits:r,points:r,preserveAspectRatio:r,r:r,rx:r,ry:r,spreadMethod:r,stopColor:r,stopOpacity:r,stroke:r,strokeDasharray:r,strokeLinecap:r,strokeOpacity:r,strokeWidth:r,textAnchor:r,transform:r,version:r,viewBox:r,x1:r,x2:r,x:r,y1:r,y2:r,y:r},DOMAttributeNames:{fillOpacity:"fill-opacity",fontFamily:"font-family",fontSize:"font-size",gradientTransform:"gradientTransform",gradientUnits:"gradientUnits",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",patternContentUnits:"patternContentUnits",patternUnits:"patternUnits",preserveAspectRatio:"preserveAspectRatio",spreadMethod:"spreadMethod",stopColor:"stop-color",stopOpacity:"stop-opacity",strokeDasharray:"stroke-dasharray",strokeLinecap:"stroke-linecap",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",textAnchor:"text-anchor",viewBox:"viewBox"}};
-t.exports=o},{"./DOMProperty":10}],76:[function(e,t){"use strict";function n(e){if("selectionStart"in e&&a.hasSelectionCapabilities(e))return{start:e.selectionStart,end:e.selectionEnd};if(document.selection){var t=document.selection.createRange();return{parentElement:t.parentElement(),text:t.text,top:t.boundingTop,left:t.boundingLeft}}var n=window.getSelection();return{anchorNode:n.anchorNode,anchorOffset:n.anchorOffset,focusNode:n.focusNode,focusOffset:n.focusOffset}}function r(e){if(!g&&null!=h&&h==u()){var t=n(h);if(!m||!p(m,t)){m=t;var r=s.getPooled(f.select,v,e);return r.type="select",r.target=h,i.accumulateTwoPhaseDispatches(r),r}}}var o=e("./EventConstants"),i=e("./EventPropagators"),a=e("./ReactInputSelection"),s=e("./SyntheticEvent"),u=e("./getActiveElement"),c=e("./isTextInputElement"),l=e("./keyOf"),p=e("./shallowEqual"),d=o.topLevelTypes,f={select:{phasedRegistrationNames:{bubbled:l({onSelect:null}),captured:l({onSelectCapture:null})},dependencies:[d.topBlur,d.topContextMenu,d.topFocus,d.topKeyDown,d.topMouseDown,d.topMouseUp,d.topSelectionChange]}},h=null,v=null,m=null,g=!1,y={eventTypes:f,extractEvents:function(e,t,n,o){switch(e){case d.topFocus:(c(t)||"true"===t.contentEditable)&&(h=t,v=n,m=null);break;case d.topBlur:h=null,v=null,m=null;break;case d.topMouseDown:g=!0;break;case d.topContextMenu:case d.topMouseUp:return g=!1,r(o);case d.topSelectionChange:case d.topKeyDown:case d.topKeyUp:return r(o)}}};t.exports=y},{"./EventConstants":15,"./EventPropagators":20,"./ReactInputSelection":56,"./SyntheticEvent":82,"./getActiveElement":106,"./isTextInputElement":121,"./keyOf":125,"./shallowEqual":135}],77:[function(e,t){"use strict";var n=Math.pow(2,53),r={createReactRootIndex:function(){return Math.ceil(Math.random()*n)}};t.exports=r},{}],78:[function(e,t){"use strict";var n=e("./EventConstants"),r=e("./EventPluginUtils"),o=e("./EventPropagators"),i=e("./SyntheticClipboardEvent"),a=e("./SyntheticEvent"),s=e("./SyntheticFocusEvent"),u=e("./SyntheticKeyboardEvent"),c=e("./SyntheticMouseEvent"),l=e("./SyntheticDragEvent"),p=e("./SyntheticTouchEvent"),d=e("./SyntheticUIEvent"),f=e("./SyntheticWheelEvent"),h=e("./invariant"),v=e("./keyOf"),m=n.topLevelTypes,g={blur:{phasedRegistrationNames:{bubbled:v({onBlur:!0}),captured:v({onBlurCapture:!0})}},click:{phasedRegistrationNames:{bubbled:v({onClick:!0}),captured:v({onClickCapture:!0})}},contextMenu:{phasedRegistrationNames:{bubbled:v({onContextMenu:!0}),captured:v({onContextMenuCapture:!0})}},copy:{phasedRegistrationNames:{bubbled:v({onCopy:!0}),captured:v({onCopyCapture:!0})}},cut:{phasedRegistrationNames:{bubbled:v({onCut:!0}),captured:v({onCutCapture:!0})}},doubleClick:{phasedRegistrationNames:{bubbled:v({onDoubleClick:!0}),captured:v({onDoubleClickCapture:!0})}},drag:{phasedRegistrationNames:{bubbled:v({onDrag:!0}),captured:v({onDragCapture:!0})}},dragEnd:{phasedRegistrationNames:{bubbled:v({onDragEnd:!0}),captured:v({onDragEndCapture:!0})}},dragEnter:{phasedRegistrationNames:{bubbled:v({onDragEnter:!0}),captured:v({onDragEnterCapture:!0})}},dragExit:{phasedRegistrationNames:{bubbled:v({onDragExit:!0}),captured:v({onDragExitCapture:!0})}},dragLeave:{phasedRegistrationNames:{bubbled:v({onDragLeave:!0}),captured:v({onDragLeaveCapture:!0})}},dragOver:{phasedRegistrationNames:{bubbled:v({onDragOver:!0}),captured:v({onDragOverCapture:!0})}},dragStart:{phasedRegistrationNames:{bubbled:v({onDragStart:!0}),captured:v({onDragStartCapture:!0})}},drop:{phasedRegistrationNames:{bubbled:v({onDrop:!0}),captured:v({onDropCapture:!0})}},focus:{phasedRegistrationNames:{bubbled:v({onFocus:!0}),captured:v({onFocusCapture:!0})}},input:{phasedRegistrationNames:{bubbled:v({onInput:!0}),captured:v({onInputCapture:!0})}},keyDown:{phasedRegistrationNames:{bubbled:v({onKeyDown:!0}),captured:v({onKeyDownCapture:!0})}},keyPress:{phasedRegistrationNames:{bubbled:v({onKeyPress:!0}),captured:v({onKeyPressCapture:!0})}},keyUp:{phasedRegistrationNames:{bubbled:v({onKeyUp:!0}),captured:v({onKeyUpCapture:!0})}},load:{phasedRegistrationNames:{bubbled:v({onLoad:!0}),captured:v({onLoadCapture:!0})}},error:{phasedRegistrationNames:{bubbled:v({onError:!0}),captured:v({onErrorCapture:!0})}},mouseDown:{phasedRegistrationNames:{bubbled:v({onMouseDown:!0}),captured:v({onMouseDownCapture:!0})}},mouseMove:{phasedRegistrationNames:{bubbled:v({onMouseMove:!0}),captured:v({onMouseMoveCapture:!0})}},mouseOut:{phasedRegistrationNames:{bubbled:v({onMouseOut:!0}),captured:v({onMouseOutCapture:!0})}},mouseOver:{phasedRegistrationNames:{bubbled:v({onMouseOver:!0}),captured:v({onMouseOverCapture:!0})}},mouseUp:{phasedRegistrationNames:{bubbled:v({onMouseUp:!0}),captured:v({onMouseUpCapture:!0})}},paste:{phasedRegistrationNames:{bubbled:v({onPaste:!0}),captured:v({onPasteCapture:!0})}},reset:{phasedRegistrationNames:{bubbled:v({onReset:!0}),captured:v({onResetCapture:!0})}},scroll:{phasedRegistrationNames:{bubbled:v({onScroll:!0}),captured:v({onScrollCapture:!0})}},submit:{phasedRegistrationNames:{bubbled:v({onSubmit:!0}),captured:v({onSubmitCapture:!0})}},touchCancel:{phasedRegistrationNames:{bubbled:v({onTouchCancel:!0}),captured:v({onTouchCancelCapture:!0})}},touchEnd:{phasedRegistrationNames:{bubbled:v({onTouchEnd:!0}),captured:v({onTouchEndCapture:!0})}},touchMove:{phasedRegistrationNames:{bubbled:v({onTouchMove:!0}),captured:v({onTouchMoveCapture:!0})}},touchStart:{phasedRegistrationNames:{bubbled:v({onTouchStart:!0}),captured:v({onTouchStartCapture:!0})}},wheel:{phasedRegistrationNames:{bubbled:v({onWheel:!0}),captured:v({onWheelCapture:!0})}}},y={topBlur:g.blur,topClick:g.click,topContextMenu:g.contextMenu,topCopy:g.copy,topCut:g.cut,topDoubleClick:g.doubleClick,topDrag:g.drag,topDragEnd:g.dragEnd,topDragEnter:g.dragEnter,topDragExit:g.dragExit,topDragLeave:g.dragLeave,topDragOver:g.dragOver,topDragStart:g.dragStart,topDrop:g.drop,topError:g.error,topFocus:g.focus,topInput:g.input,topKeyDown:g.keyDown,topKeyPress:g.keyPress,topKeyUp:g.keyUp,topLoad:g.load,topMouseDown:g.mouseDown,topMouseMove:g.mouseMove,topMouseOut:g.mouseOut,topMouseOver:g.mouseOver,topMouseUp:g.mouseUp,topPaste:g.paste,topReset:g.reset,topScroll:g.scroll,topSubmit:g.submit,topTouchCancel:g.touchCancel,topTouchEnd:g.touchEnd,topTouchMove:g.touchMove,topTouchStart:g.touchStart,topWheel:g.wheel};for(var C in y)y[C].dependencies=[C];var E={eventTypes:g,executeDispatch:function(e,t,n){var o=r.executeDispatch(e,t,n);o===!1&&(e.stopPropagation(),e.preventDefault())},extractEvents:function(e,t,n,r){var v=y[e];if(!v)return null;var g;switch(e){case m.topInput:case m.topLoad:case m.topError:case m.topReset:case m.topSubmit:g=a;break;case m.topKeyPress:if(0===r.charCode)return null;case m.topKeyDown:case m.topKeyUp:g=u;break;case m.topBlur:case m.topFocus:g=s;break;case m.topClick:if(2===r.button)return null;case m.topContextMenu:case m.topDoubleClick:case m.topMouseDown:case m.topMouseMove:case m.topMouseOut:case m.topMouseOver:case m.topMouseUp:g=c;break;case m.topDrag:case m.topDragEnd:case m.topDragEnter:case m.topDragExit:case m.topDragLeave:case m.topDragOver:case m.topDragStart:case m.topDrop:g=l;break;case m.topTouchCancel:case m.topTouchEnd:case m.topTouchMove:case m.topTouchStart:g=p;break;case m.topScroll:g=d;break;case m.topWheel:g=f;break;case m.topCopy:case m.topCut:case m.topPaste:g=i}h(g);var C=g.getPooled(v,n,r);return o.accumulateTwoPhaseDispatches(C),C}};t.exports=E},{"./EventConstants":15,"./EventPluginUtils":19,"./EventPropagators":20,"./SyntheticClipboardEvent":79,"./SyntheticDragEvent":81,"./SyntheticEvent":82,"./SyntheticFocusEvent":83,"./SyntheticKeyboardEvent":85,"./SyntheticMouseEvent":86,"./SyntheticTouchEvent":87,"./SyntheticUIEvent":88,"./SyntheticWheelEvent":89,"./invariant":118,"./keyOf":125}],79:[function(e,t){"use strict";function n(e,t,n){r.call(this,e,t,n)}var r=e("./SyntheticEvent"),o={clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}};r.augmentClass(n,o),t.exports=n},{"./SyntheticEvent":82}],80:[function(e,t){"use strict";function n(e,t,n){r.call(this,e,t,n)}var r=e("./SyntheticEvent"),o={data:null};r.augmentClass(n,o),t.exports=n},{"./SyntheticEvent":82}],81:[function(e,t){"use strict";function n(e,t,n){r.call(this,e,t,n)}var r=e("./SyntheticMouseEvent"),o={dataTransfer:null};r.augmentClass(n,o),t.exports=n},{"./SyntheticMouseEvent":86}],82:[function(e,t){"use strict";function n(e,t,n){this.dispatchConfig=e,this.dispatchMarker=t,this.nativeEvent=n;var r=this.constructor.Interface;for(var i in r)if(r.hasOwnProperty(i)){var a=r[i];this[i]=a?a(n):n[i]}var s=null!=n.defaultPrevented?n.defaultPrevented:n.returnValue===!1;this.isDefaultPrevented=s?o.thatReturnsTrue:o.thatReturnsFalse,this.isPropagationStopped=o.thatReturnsFalse}var r=e("./PooledClass"),o=e("./emptyFunction"),i=e("./getEventTarget"),a=e("./merge"),s=e("./mergeInto"),u={type:null,target:i,currentTarget:o.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null};s(n.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e.preventDefault?e.preventDefault():e.returnValue=!1,this.isDefaultPrevented=o.thatReturnsTrue},stopPropagation:function(){var e=this.nativeEvent;e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,this.isPropagationStopped=o.thatReturnsTrue},persist:function(){this.isPersistent=o.thatReturnsTrue},isPersistent:o.thatReturnsFalse,destructor:function(){var e=this.constructor.Interface;for(var t in e)this[t]=null;this.dispatchConfig=null,this.dispatchMarker=null,this.nativeEvent=null}}),n.Interface=u,n.augmentClass=function(e,t){var n=this,o=Object.create(n.prototype);s(o,e.prototype),e.prototype=o,e.prototype.constructor=e,e.Interface=a(n.Interface,t),e.augmentClass=n.augmentClass,r.addPoolingTo(e,r.threeArgumentPooler)},r.addPoolingTo(n,r.threeArgumentPooler),t.exports=n},{"./PooledClass":26,"./emptyFunction":100,"./getEventTarget":109,"./merge":128,"./mergeInto":130}],83:[function(e,t){"use strict";function n(e,t,n){r.call(this,e,t,n)}var r=e("./SyntheticUIEvent"),o={relatedTarget:null};r.augmentClass(n,o),t.exports=n},{"./SyntheticUIEvent":88}],84:[function(e,t){"use strict";function n(e,t,n){r.call(this,e,t,n)}var r=e("./SyntheticEvent"),o={data:null};r.augmentClass(n,o),t.exports=n},{"./SyntheticEvent":82}],85:[function(e,t){"use strict";function n(e,t,n){r.call(this,e,t,n)}var r=e("./SyntheticUIEvent"),o=e("./getEventKey"),i=e("./getEventModifierState"),a={key:o,location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:i,charCode:function(e){return"keypress"===e.type?"charCode"in e?e.charCode:e.keyCode:0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return e.keyCode||e.charCode}};r.augmentClass(n,a),t.exports=n},{"./SyntheticUIEvent":88,"./getEventKey":107,"./getEventModifierState":108}],86:[function(e,t){"use strict";function n(e,t,n){r.call(this,e,t,n)}var r=e("./SyntheticUIEvent"),o=e("./ViewportMetrics"),i=e("./getEventModifierState"),a={screenX:null,screenY:null,clientX:null,clientY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:i,button:function(e){var t=e.button;return"which"in e?t:2===t?2:4===t?1:0},buttons:null,relatedTarget:function(e){return e.relatedTarget||(e.fromElement===e.srcElement?e.toElement:e.fromElement)},pageX:function(e){return"pageX"in e?e.pageX:e.clientX+o.currentScrollLeft},pageY:function(e){return"pageY"in e?e.pageY:e.clientY+o.currentScrollTop}};r.augmentClass(n,a),t.exports=n},{"./SyntheticUIEvent":88,"./ViewportMetrics":91,"./getEventModifierState":108}],87:[function(e,t){"use strict";function n(e,t,n){r.call(this,e,t,n)}var r=e("./SyntheticUIEvent"),o=e("./getEventModifierState"),i={touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:o};r.augmentClass(n,i),t.exports=n},{"./SyntheticUIEvent":88,"./getEventModifierState":108}],88:[function(e,t){"use strict";function n(e,t,n){r.call(this,e,t,n)}var r=e("./SyntheticEvent"),o=e("./getEventTarget"),i={view:function(e){if(e.view)return e.view;var t=o(e);if(null!=t&&t.window===t)return t;var n=t.ownerDocument;return n?n.defaultView||n.parentWindow:window},detail:function(e){return e.detail||0}};r.augmentClass(n,i),t.exports=n},{"./SyntheticEvent":82,"./getEventTarget":109}],89:[function(e,t){"use strict";function n(e,t,n){r.call(this,e,t,n)}var r=e("./SyntheticMouseEvent"),o={deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:null,deltaMode:null};r.augmentClass(n,o),t.exports=n},{"./SyntheticMouseEvent":86}],90:[function(e,t){"use strict";var n=e("./invariant"),r={reinitializeTransaction:function(){this.transactionWrappers=this.getTransactionWrappers(),this.wrapperInitData?this.wrapperInitData.length=0:this.wrapperInitData=[],this._isInTransaction=!1},_isInTransaction:!1,getTransactionWrappers:null,isInTransaction:function(){return!!this._isInTransaction},perform:function(e,t,r,o,i,a,s,u){n(!this.isInTransaction());var c,l;try{this._isInTransaction=!0,c=!0,this.initializeAll(0),l=e.call(t,r,o,i,a,s,u),c=!1}finally{try{if(c)try{this.closeAll(0)}catch(p){}else this.closeAll(0)}finally{this._isInTransaction=!1}}return l},initializeAll:function(e){for(var t=this.transactionWrappers,n=e;n<t.length;n++){var r=t[n];try{this.wrapperInitData[n]=o.OBSERVED_ERROR,this.wrapperInitData[n]=r.initialize?r.initialize.call(this):null}finally{if(this.wrapperInitData[n]===o.OBSERVED_ERROR)try{this.initializeAll(n+1)}catch(i){}}}},closeAll:function(e){n(this.isInTransaction());for(var t=this.transactionWrappers,r=e;r<t.length;r++){var i,a=t[r],s=this.wrapperInitData[r];try{i=!0,s!==o.OBSERVED_ERROR&&a.close&&a.close.call(this,s),i=!1}finally{if(i)try{this.closeAll(r+1)}catch(u){}}}this.wrapperInitData.length=0}},o={Mixin:r,OBSERVED_ERROR:{}};t.exports=o},{"./invariant":118}],91:[function(e,t){"use strict";var n=e("./getUnboundedScrollPosition"),r={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(){var e=n(window);r.currentScrollLeft=e.x,r.currentScrollTop=e.y}};t.exports=r},{"./getUnboundedScrollPosition":114}],92:[function(e,t){"use strict";function n(e,t){if(r(null!=t),null==e)return t;var n=Array.isArray(e),o=Array.isArray(t);return n?e.concat(t):o?[e].concat(t):[e,t]}var r=e("./invariant");t.exports=n},{"./invariant":118}],93:[function(e,t){"use strict";function n(e){for(var t=1,n=0,o=0;o<e.length;o++)t=(t+e.charCodeAt(o))%r,n=(n+t)%r;return t|n<<16}var r=65521;t.exports=n},{}],94:[function(e,t){function n(e,t){return e&&t?e===t?!0:r(e)?!1:r(t)?n(e,t.parentNode):e.contains?e.contains(t):e.compareDocumentPosition?!!(16&e.compareDocumentPosition(t)):!1:!1}var r=e("./isTextNode");t.exports=n},{"./isTextNode":122}],95:[function(e,t){function n(e,t,n,r,o,i){e=e||{};for(var a,s=[t,n,r,o,i],u=0;s[u];){a=s[u++];for(var c in a)e[c]=a[c];a.hasOwnProperty&&a.hasOwnProperty("toString")&&"undefined"!=typeof a.toString&&e.toString!==a.toString&&(e.toString=a.toString)}return e}t.exports=n},{}],96:[function(e,t){function n(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"length"in e&&!("setInterval"in e)&&"number"!=typeof e.nodeType&&(Array.isArray(e)||"callee"in e||"item"in e)}function r(e){return n(e)?Array.isArray(e)?e.slice():o(e):[e]}var o=e("./toArray");t.exports=r},{"./toArray":137}],97:[function(e,t){"use strict";function n(e){var t=r.createClass({displayName:"ReactFullPageComponent"+(e.type.displayName||""),componentWillUnmount:function(){o(!1)},render:function(){return this.transferPropsTo(e(null,this.props.children))}});return t}var r=e("./ReactCompositeComponent"),o=e("./invariant");t.exports=n},{"./ReactCompositeComponent":33,"./invariant":118}],98:[function(e,t){function n(e){var t=e.match(c);return t&&t[1].toLowerCase()}function r(e,t){var r=u;s(!!u);var o=n(e),c=o&&a(o);if(c){r.innerHTML=c[1]+e+c[2];for(var l=c[0];l--;)r=r.lastChild}else r.innerHTML=e;var p=r.getElementsByTagName("script");p.length&&(s(t),i(p).forEach(t));for(var d=i(r.childNodes);r.lastChild;)r.removeChild(r.lastChild);return d}var o=e("./ExecutionEnvironment"),i=e("./createArrayFrom"),a=e("./getMarkupWrap"),s=e("./invariant"),u=o.canUseDOM?document.createElement("div"):null,c=/^\s*<(\w+)/;t.exports=r},{"./ExecutionEnvironment":21,"./createArrayFrom":96,"./getMarkupWrap":110,"./invariant":118}],99:[function(e,t){"use strict";function n(e,t){var n=null==t||"boolean"==typeof t||""===t;if(n)return"";var r=isNaN(t);return r||0===t||o.hasOwnProperty(e)&&o[e]?""+t:("string"==typeof t&&(t=t.trim()),t+"px")}var r=e("./CSSProperty"),o=r.isUnitlessNumber;t.exports=n},{"./CSSProperty":3}],100:[function(e,t){function n(e){return function(){return e}}function r(){}var o=e("./copyProperties");o(r,{thatReturns:n,thatReturnsFalse:n(!1),thatReturnsTrue:n(!0),thatReturnsNull:n(null),thatReturnsThis:function(){return this},thatReturnsArgument:function(e){return e}}),t.exports=r},{"./copyProperties":95}],101:[function(e,t){"use strict";var n={};t.exports=n},{}],102:[function(e,t){"use strict";function n(e){return o[e]}function r(e){return(""+e).replace(i,n)}var o={"&":"&",">":">","<":"<",'"':""","'":"'"},i=/[&><"']/g;t.exports=r},{}],103:[function(e,t){"use strict";function n(e,t,n){var r=e,o=!r.hasOwnProperty(n);o&&null!=t&&(r[n]=t)}function r(e){if(null==e)return e;var t={};return o(e,n,t),t}{var o=e("./traverseAllChildren");e("./warning")}t.exports=r},{"./traverseAllChildren":138,"./warning":139}],104:[function(e,t){"use strict";function n(e){e.disabled||e.focus()}t.exports=n},{}],105:[function(e,t){"use strict";var n=function(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)};t.exports=n},{}],106:[function(e,t){function n(){try{return document.activeElement||document.body}catch(e){return document.body}}t.exports=n},{}],107:[function(e,t){"use strict";function n(e){if(e.key){var t=o[e.key]||e.key;if("Unidentified"!==t)return t}if("keypress"===e.type){var n="charCode"in e?e.charCode:e.keyCode;return 13===n?"Enter":String.fromCharCode(n)}return"keydown"===e.type||"keyup"===e.type?i[e.keyCode]||"Unidentified":void r(!1)}var r=e("./invariant"),o={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},i={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};t.exports=n},{"./invariant":118}],108:[function(e,t){"use strict";function n(e){var t=this,n=t.nativeEvent;if(n.getModifierState)return n.getModifierState(e);var r=o[e];return r?!!n[r]:!1}function r(){return n}var o={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};t.exports=r},{}],109:[function(e,t){"use strict";function n(e){var t=e.target||e.srcElement||window;return 3===t.nodeType?t.parentNode:t}t.exports=n},{}],110:[function(e,t){function n(e){return o(!!i),p.hasOwnProperty(e)||(e="*"),a.hasOwnProperty(e)||(i.innerHTML="*"===e?"<link />":"<"+e+"></"+e+">",a[e]=!i.firstChild),a[e]?p[e]:null}var r=e("./ExecutionEnvironment"),o=e("./invariant"),i=r.canUseDOM?document.createElement("div"):null,a={circle:!0,defs:!0,ellipse:!0,g:!0,line:!0,linearGradient:!0,path:!0,polygon:!0,polyline:!0,radialGradient:!0,rect:!0,stop:!0,text:!0},s=[1,'<select multiple="true">',"</select>"],u=[1,"<table>","</table>"],c=[3,"<table><tbody><tr>","</tr></tbody></table>"],l=[1,"<svg>","</svg>"],p={"*":[1,"?<div>","</div>"],area:[1,"<map>","</map>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],legend:[1,"<fieldset>","</fieldset>"],param:[1,"<object>","</object>"],tr:[2,"<table><tbody>","</tbody></table>"],optgroup:s,option:s,caption:u,colgroup:u,tbody:u,tfoot:u,thead:u,td:c,th:c,circle:l,defs:l,ellipse:l,g:l,line:l,linearGradient:l,path:l,polygon:l,polyline:l,radialGradient:l,rect:l,stop:l,text:l};t.exports=n},{"./ExecutionEnvironment":21,"./invariant":118}],111:[function(e,t){"use strict";function n(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function r(e){for(;e;){if(e.nextSibling)return e.nextSibling;e=e.parentNode}}function o(e,t){for(var o=n(e),i=0,a=0;o;){if(3==o.nodeType){if(a=i+o.textContent.length,t>=i&&a>=t)return{node:o,offset:t-i};i=a}o=n(r(o))}}t.exports=o},{}],112:[function(e,t){"use strict";function n(e){return e?e.nodeType===r?e.documentElement:e.firstChild:null}var r=9;t.exports=n},{}],113:[function(e,t){"use strict";function n(){return!o&&r.canUseDOM&&(o="textContent"in document.documentElement?"textContent":"innerText"),o}var r=e("./ExecutionEnvironment"),o=null;t.exports=n},{"./ExecutionEnvironment":21}],114:[function(e,t){"use strict";function n(e){return e===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:e.scrollLeft,y:e.scrollTop}}t.exports=n},{}],115:[function(e,t){function n(e){return e.replace(r,"-$1").toLowerCase()}var r=/([A-Z])/g;t.exports=n},{}],116:[function(e,t){"use strict";function n(e){return r(e).replace(o,"-ms-")}var r=e("./hyphenate"),o=/^ms-/;t.exports=n},{"./hyphenate":115}],117:[function(e,t){"use strict";function n(e){return e&&"function"==typeof e.type&&"function"==typeof e.type.prototype.mountComponent&&"function"==typeof e.type.prototype.receiveComponent}function r(e){return o(n(e)),new e.type(e)}var o=e("./invariant");t.exports=r},{"./invariant":118}],118:[function(e,t){"use strict";var n=function(e,t,n,r,o,i,a,s){if(!e){var u;if(void 0===t)u=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,o,i,a,s],l=0;u=new Error("Invariant Violation: "+t.replace(/%s/g,function(){return c[l++]}))}throw u.framesToPop=1,u}};t.exports=n},{}],119:[function(e,t){"use strict";function n(e,t){if(!o.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,i=n in document;if(!i){var a=document.createElement("div");a.setAttribute(n,"return;"),i="function"==typeof a[n]}return!i&&r&&"wheel"===e&&(i=document.implementation.hasFeature("Events.wheel","3.0")),i}var r,o=e("./ExecutionEnvironment");o.canUseDOM&&(r=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),t.exports=n},{"./ExecutionEnvironment":21}],120:[function(e,t){function n(e){return!(!e||!("function"==typeof Node?e instanceof Node:"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName))}t.exports=n},{}],121:[function(e,t){"use strict";function n(e){return e&&("INPUT"===e.nodeName&&r[e.type]||"TEXTAREA"===e.nodeName)}var r={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};t.exports=n},{}],122:[function(e,t){function n(e){return r(e)&&3==e.nodeType}var r=e("./isNode");t.exports=n},{"./isNode":120}],123:[function(e,t){"use strict";function n(e){e||(e="");var t,n=arguments.length;if(n>1)for(var r=1;n>r;r++)t=arguments[r],t&&(e+=" "+t);return e}t.exports=n},{}],124:[function(e,t){"use strict";var n=e("./invariant"),r=function(e){var t,r={};n(e instanceof Object&&!Array.isArray(e));for(t in e)e.hasOwnProperty(t)&&(r[t]=t);return r};t.exports=r},{"./invariant":118}],125:[function(e,t){var n=function(e){var t;for(t in e)if(e.hasOwnProperty(t))return t;return null};t.exports=n},{}],126:[function(e,t){"use strict";function n(e,t,n){if(!e)return null;var r=0,o={};for(var i in e)e.hasOwnProperty(i)&&(o[i]=t.call(n,e[i],i,r++));return o}t.exports=n},{}],127:[function(e,t){"use strict";function n(e){var t={};return function(n){return t.hasOwnProperty(n)?t[n]:t[n]=e.call(this,n)}}t.exports=n},{}],128:[function(e,t){"use strict";var n=e("./mergeInto"),r=function(e,t){var r={};return n(r,e),n(r,t),r};t.exports=r},{"./mergeInto":130}],129:[function(e,t){"use strict";var n=e("./invariant"),r=e("./keyMirror"),o=36,i=function(e){return"object"!=typeof e||null===e},a={MAX_MERGE_DEPTH:o,isTerminal:i,normalizeMergeArg:function(e){return void 0===e||null===e?{}:e},checkMergeArrayArgs:function(e,t){n(Array.isArray(e)&&Array.isArray(t))},checkMergeObjectArgs:function(e,t){a.checkMergeObjectArg(e),a.checkMergeObjectArg(t)},checkMergeObjectArg:function(e){n(!i(e)&&!Array.isArray(e))},checkMergeIntoObjectArg:function(e){n(!(i(e)&&"function"!=typeof e||Array.isArray(e)))},checkMergeLevel:function(e){n(o>e)},checkArrayStrategy:function(e){n(void 0===e||e in a.ArrayStrategies)},ArrayStrategies:r({Clobber:!0,IndexByIndex:!0})};t.exports=a},{"./invariant":118,"./keyMirror":124}],130:[function(e,t){"use strict";function n(e,t){if(i(e),null!=t){o(t);for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])}}var r=e("./mergeHelpers"),o=r.checkMergeObjectArg,i=r.checkMergeIntoObjectArg;t.exports=n},{"./mergeHelpers":129}],131:[function(e,t){"use strict";var n=function(e,t){var n;for(n in t)t.hasOwnProperty(n)&&(e.prototype[n]=t[n])};t.exports=n},{}],132:[function(e,t){"use strict";function n(e){r(e&&!/[^a-z0-9_]/.test(e))}var r=e("./invariant");t.exports=n},{"./invariant":118}],133:[function(e,t){"use strict";function n(e){return o(r.isValidDescriptor(e)),e}var r=e("./ReactDescriptor"),o=e("./invariant");t.exports=n},{"./ReactDescriptor":49,"./invariant":118}],134:[function(e,t){"use strict";var n=e("./ExecutionEnvironment"),r=function(e,t){e.innerHTML=t};if(n.canUseDOM){var o=document.createElement("div");o.innerHTML=" ",""===o.innerHTML&&(r=function(e,t){if(e.parentNode&&e.parentNode.replaceChild(e,e),t.match(/^[ \r\n\t\f]/)||"<"===t[0]&&(-1!==t.indexOf("<noscript")||-1!==t.indexOf("<script")||-1!==t.indexOf("<style")||-1!==t.indexOf("<meta")||-1!==t.indexOf("<link"))){e.innerHTML=""+t;var n=e.firstChild;1===n.data.length?e.removeChild(n):n.deleteData(0,1)}else e.innerHTML=t})}t.exports=r},{"./ExecutionEnvironment":21}],135:[function(e,t){"use strict";function n(e,t){if(e===t)return!0;var n;for(n in e)if(e.hasOwnProperty(n)&&(!t.hasOwnProperty(n)||e[n]!==t[n]))return!1;for(n in t)if(t.hasOwnProperty(n)&&!e.hasOwnProperty(n))return!1;return!0}t.exports=n},{}],136:[function(e,t){"use strict";function n(e,t){return e&&t&&e.type===t.type&&(e.props&&e.props.key)===(t.props&&t.props.key)&&e._owner===t._owner?!0:!1}t.exports=n},{}],137:[function(e,t){function n(e){var t=e.length;if(r(!Array.isArray(e)&&("object"==typeof e||"function"==typeof e)),r("number"==typeof t),r(0===t||t-1 in e),e.hasOwnProperty)try{return Array.prototype.slice.call(e)}catch(n){}for(var o=Array(t),i=0;t>i;i++)o[i]=e[i];return o}var r=e("./invariant");t.exports=n},{"./invariant":118}],138:[function(e,t){"use strict";function n(e){return d[e]}function r(e,t){return e&&e.props&&null!=e.props.key?i(e.props.key):t.toString(36)}function o(e){return(""+e).replace(f,n)}function i(e){return"$"+o(e)}function a(e,t,n){return null==e?0:h(e,"",0,t,n)}var s=e("./ReactInstanceHandles"),u=e("./ReactTextComponent"),c=e("./invariant"),l=s.SEPARATOR,p=":",d={"=":"=0",".":"=1",":":"=2"},f=/[=.:]/g,h=function(e,t,n,o,a){var s=0;if(Array.isArray(e))for(var d=0;d<e.length;d++){var f=e[d],v=t+(t?p:l)+r(f,d),m=n+s;s+=h(f,v,m,o,a)}else{var g=typeof e,y=""===t,C=y?l+r(e,0):t;if(null==e||"boolean"===g)o(a,null,C,n),s=1;else if(e.type&&e.type.prototype&&e.type.prototype.mountComponentIntoNode)o(a,e,C,n),s=1;else if("object"===g){c(!e||1!==e.nodeType);for(var E in e)e.hasOwnProperty(E)&&(s+=h(e[E],t+(t?p:l)+i(E)+p+r(e[E],0),n+s,o,a))}else if("string"===g){var R=u(e);o(a,R,C,n),s+=1}else if("number"===g){var M=u(""+e);o(a,M,C,n),s+=1}}return s};t.exports=a},{"./ReactInstanceHandles":57,"./ReactTextComponent":73,"./invariant":118}],139:[function(e,t){"use strict";var n=e("./emptyFunction"),r=n;t.exports=r},{"./emptyFunction":100}]},{},[27])(27)});
\ No newline at end of file
diff --git a/examples/todos/todos_init/data.json b/examples/todos/todos_init/data.json
deleted file mode 100644
index 7fde22e..0000000
--- a/examples/todos/todos_init/data.json
+++ /dev/null
@@ -1,36 +0,0 @@
-[
- {"name": "Meteor Principles",
- "contents": [
- ["Data on the Wire", "Simplicity", "Better UX", "Fun"],
- ["One Language", "Simplicity", "Fun"],
- ["Database Everywhere", "Simplicity"],
- ["Latency Compensation", "Better UX"],
- ["Full Stack Reactivity", "Better UX", "Fun"],
- ["Embrace the Ecosystem", "Fun"],
- ["Simplicity Equals Productivity", "Simplicity", "Fun"]
- ]
- },
- {"name": "Languages",
- "contents": [
- ["Lisp", "GC"],
- ["C", "Linked"],
- ["C++", "Objects", "Linked"],
- ["Python", "GC", "Objects"],
- ["Ruby", "GC", "Objects"],
- ["JavaScript", "GC", "Objects"],
- ["Scala", "GC", "Objects"],
- ["Erlang", "GC"],
- ["6502 Assembly", "Linked"]
- ]
- },
- {"name": "Favorite Scientists",
- "contents": [
- ["Ada Lovelace", "Computer Science"],
- ["Grace Hopper", "Computer Science"],
- ["Marie Curie", "Physics", "Chemistry"],
- ["Carl Friedrich Gauss", "Math", "Physics"],
- ["Nikola Tesla", "Physics"],
- ["Claude Shannon", "Math", "Computer Science"]
- ]
- }
-]
diff --git a/examples/todos/todos_init/main.go b/examples/todos/todos_init/main.go
deleted file mode 100644
index e2f9c99..0000000
--- a/examples/todos/todos_init/main.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// TODO(kash): Rewrite this to use the new dir/object store api.
-// +build ignore
-
-// todos_init reads data.json and populates the store with initial data.
-package main
-
-import (
- "encoding/json"
- "flag"
- "fmt"
- "os"
- "os/user"
- "path/filepath"
- "strings"
-
- "veyron/examples/todos/schema"
- "veyron2/context"
- "veyron2/rt"
- "veyron.io/store/veyron2/storage"
- "veyron.io/store/veyron2/storage/vstore"
- "veyron2/vlog"
-)
-
-var (
- storeName string
- dataPath = flag.String("data-path", "data.json", "Path to data JSON file")
-)
-
-func init() {
- username := "unknown"
- if u, err := user.Current(); err == nil {
- username = u.Username
- }
- hostname := "unknown"
- if h, err := os.Hostname(); err == nil {
- hostname = h
- }
- dir := "global/vstore/" + hostname + "/" + username
- flag.StringVar(&storeName, "store", dir, "Name of the Veyron store")
-}
-
-// List is the JSON representation for schema.List.
-// Note, we use this representation for parity with the Meteor example.
-// https://www.meteor.com/examples/todos
-type List struct {
- Name string
- // Each element corresponds to a schema.Item; each item is represented as a
- // list where the first element is the item name and the remaining elements
- // are tags.
- Contents [][]string
-}
-
-// state is the initial store state.
-type state struct {
- store storage.Store
- ctx context.T
- storeRoot string // The name of the root of the store.
- tx storage.Transaction // Current transaction; nil if there's no transaction.
-}
-
-// newState returns a fresh state.
-func newState(ctx context.T, st storage.Store, storeRoot string) *state {
- return &state{store: st, ctx: ctx, storeRoot: storeRoot}
-}
-
-// put adds a value to the store, creating the path to the value if it doesn't
-// already exist.
-func (st *state) put(path string, v interface{}) {
- vlog.Infof("Storing %q = %+v", path, v)
- st.makeParentDirs(path)
- if _, err := st.tx.Bind(path).Put(st.ctx, v); err != nil {
- vlog.Errorf("put failed: %s: %s", path, err)
- return
- }
-}
-
-// makeParentDirs creates the directories in a path if they do not already
-// exist.
-func (st *state) makeParentDirs(path string) {
- l := strings.Split(path, "/")
- for i, _ := range l {
- prefix := filepath.Join(l[:i]...)
- o := st.tx.Bind(prefix)
- if exist, err := o.Exists(st.ctx); err != nil {
- vlog.Infof("Error checking existence at %q: %s", prefix, err)
- } else if !exist {
- if _, err := o.Put(st.ctx, &schema.Dir{}); err != nil {
- vlog.Infof("Error creating parent %q: %s", prefix, err)
- }
- }
- }
-}
-
-// newTransaction starts a new transaction.
-// TODO(kash): Saving the transaction in st is not a good pattern to have in
-// examples. It is better to pass a transaction around than risk the race
-// condition of st being used from multiple threads.
-func (st *state) newTransaction() {
- st.tx = st.store.NewTransaction(st.ctx, st.storeRoot)
-}
-
-// commit commits the current transaction.
-func (st *state) commit() {
- if st.tx == nil {
- vlog.Fatalf("No transaction to commit")
- }
- err := st.tx.Commit(st.ctx)
- st.tx = nil
- if err != nil {
- vlog.Errorf("Failed to commit transaction: %s", err)
- }
-}
-
-// storeList saves a schema.List to the store with name /lists/<Name>, and also
-// saves the list's child items.
-func (st *state) storeList(l *List) {
- x := &schema.List{
- Name: l.Name,
- }
- path := "/lists/" + x.Name
- st.put(path, x)
-
- // Store this list's child items.
- // TODO(sadovsky): Ensure that order is preserved, and is reflected in the UI.
- for i, v := range l.Contents {
- st.storeItem(path, i, v[0], v[1:])
- }
-}
-
-// storeItem saves a schema.Item to the store with name /<listPath>/Items/<id>.
-// Note that <id> is defined by storeList to be the position of the item in its
-// parent list.
-func (st *state) storeItem(listPath string, id int, text string, tags []string) {
- x := &schema.Item{
- Text: text,
- Done: false,
- Tags: tags,
- }
- path := fmt.Sprintf("%s/Items/%d", listPath, id)
- st.put(path, x)
-}
-
-// processJSONFile saves the contents of the JSON file to the store.
-func (st *state) processJSONFile(path string) error {
- vlog.Infof("Loading file %s", path)
- file, err := os.Open(path)
- if err != nil {
- return fmt.Errorf("Can't open %q: %s", path, err)
- }
- defer file.Close()
-
- lists := make([]*List, 0)
- decoder := json.NewDecoder(file)
- if err := decoder.Decode(&lists); err != nil {
- return fmt.Errorf("Can't decode: %s", err)
- }
-
- st.newTransaction()
- for _, v := range lists {
- st.storeList(v)
- }
- st.commit()
- return nil
-}
-
-// main reads the data JSON file and populates the store.
-func main() {
- r := rt.Init()
- ctx := r.NewContext()
-
- vlog.Infof("Binding to store on %s", storeName)
- state := newState(ctx, vstore.New(), storeName)
-
- if err := state.processJSONFile(*dataPath); err != nil {
- vlog.Errorf("Failed to write data: %s", err)
- }
-}
diff --git a/examples/tunnel/lib/forward.go b/examples/tunnel/lib/forward.go
deleted file mode 100644
index d70c238..0000000
--- a/examples/tunnel/lib/forward.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package lib
-
-import (
- "fmt"
- "io"
- "net"
-)
-
-type sender interface {
- Send([]uint8) error
-}
-type receiver interface {
- Advance() bool
-
- Value() []uint8
-
- Err() error
-}
-
-// Forward forwards data read from net.Conn to a TunnelForwardStream or a TunnelServiceForwardStream.
-func Forward(conn net.Conn, s sender, r receiver) error {
- defer conn.Close()
- // Both conn2stream and stream2conn will write to the channel exactly
- // once.
- // Forward reads from the channel exactly once.
- // A buffered channel is used to prevent the other write to the channel
- // from blocking.
- done := make(chan error, 1)
- go conn2stream(conn, s, done)
- go stream2conn(r, conn, done)
- return <-done
-}
-
-func conn2stream(r io.Reader, s sender, done chan error) {
- var buf [2048]byte
- for {
- n, err := r.Read(buf[:])
- if err == io.EOF {
- done <- nil
- return
- }
- if err != nil {
- done <- err
- return
- }
- if err := s.Send(buf[:n]); err != nil {
- done <- err
- return
- }
- }
-}
-
-func stream2conn(r receiver, w io.Writer, done chan error) {
- for r.Advance() {
- buf := r.Value()
-
- if n, err := w.Write(buf); n != len(buf) || err != nil {
- done <- fmt.Errorf("conn.Write returned (%d, %v) want (%d, nil)", n, err, len(buf))
- return
- }
- }
- done <- r.Err()
-}
diff --git a/examples/tunnel/lib/terminal.go b/examples/tunnel/lib/terminal.go
deleted file mode 100644
index 1e33bb1..0000000
--- a/examples/tunnel/lib/terminal.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package lib
-
-import (
- "errors"
- "os/exec"
- "strings"
- "syscall"
- "unsafe"
-
- "veyron2/vlog"
-)
-
-// Used with ioctl TIOCGWINSZ and TIOCSWINSZ.
-type Winsize struct {
- Row uint16
- Col uint16
- Xpixel uint16
- Ypixel uint16
-}
-
-// SetWindowSize sets the terminal's window size.
-func SetWindowSize(fd uintptr, ws Winsize) error {
- vlog.Infof("Setting window size: %v", ws)
- ret, _, _ := syscall.Syscall(
- syscall.SYS_IOCTL,
- fd,
- uintptr(syscall.TIOCSWINSZ),
- uintptr(unsafe.Pointer(&ws)))
- if int(ret) == -1 {
- return errors.New("ioctl(TIOCSWINSZ) failed")
- }
- return nil
-}
-
-// GetWindowSize gets the terminal's window size.
-func GetWindowSize() (*Winsize, error) {
- ws := &Winsize{}
- ret, _, _ := syscall.Syscall(
- syscall.SYS_IOCTL,
- uintptr(syscall.Stdin),
- uintptr(syscall.TIOCGWINSZ),
- uintptr(unsafe.Pointer(ws)))
- if int(ret) == -1 {
- return nil, errors.New("ioctl(TIOCGWINSZ) failed")
- }
- return ws, nil
-}
-
-func EnterRawTerminalMode() string {
- var savedBytes []byte
- var err error
- if savedBytes, err = exec.Command("stty", "-F", "/dev/tty", "-g").Output(); err != nil {
- vlog.Infof("Failed to save terminal settings: %q (%v)", savedBytes, err)
- }
- saved := strings.TrimSpace(string(savedBytes))
-
- args := []string{
- "-F", "/dev/tty",
- // Don't buffer stdin. Read characters as they are typed.
- "-icanon", "min", "1", "time", "0",
- // Turn off local echo of input characters.
- "-echo", "-echoe", "-echok", "-echonl",
- // Disable interrupt, quit, and suspend special characters.
- "-isig",
- // Ignore characters with parity errors.
- "ignpar",
- // Disable translate newline to carriage return.
- "-inlcr",
- // Disable ignore carriage return.
- "-igncr",
- // Disable translate carriage return to newline.
- "-icrnl",
- // Disable flow control.
- "-ixon", "-ixany", "-ixoff",
- // Disable non-POSIX special characters.
- "-iexten",
- }
- if out, err := exec.Command("stty", args...).CombinedOutput(); err != nil {
- vlog.Infof("stty failed (%v) (%q)", err, out)
- }
-
- return string(saved)
-}
-
-func RestoreTerminalSettings(saved string) {
- args := []string{
- "-F", "/dev/tty",
- saved,
- }
- if out, err := exec.Command("stty", args...).CombinedOutput(); err != nil {
- vlog.Infof("stty failed (%v) (%q)", err, out)
- }
-}
diff --git a/examples/tunnel/tunnel.vdl b/examples/tunnel/tunnel.vdl
deleted file mode 100644
index 3098e0e..0000000
--- a/examples/tunnel/tunnel.vdl
+++ /dev/null
@@ -1,42 +0,0 @@
-package tunnel
-
-import "veyron2/security"
-
-// Tunnel creates a network tunnel from the client to the server.
-
-type Tunnel interface {
- // The Forward method is used for network forwarding. All the data sent over
- // the byte stream is forwarded to the requested network address and all the
- // data received from that network connection is sent back in the reply
- // stream.
- Forward(network, address string) stream<[]byte, []byte> error {security.AdminLabel}
-
- // The Shell method is used to either run shell commands remotely, or to open
- // an interactive shell. The data received over the byte stream is sent to the
- // shell's stdin, and the data received from the shell's stdout and stderr is
- // sent back in the reply stream. It returns the exit status of the shell
- // command.
- Shell(command string, shellOpts ShellOpts) stream<ClientShellPacket, ServerShellPacket> (int32, error) {security.AdminLabel}
-}
-
-type ShellOpts struct {
- UsePty bool // Whether to open a pseudo-terminal
- Environment []string // Environment variables to pass to the remote shell.
- Rows, Cols uint32 // Window size.
-}
-
-type ClientShellPacket struct {
- // Bytes going to the shell's stdin.
- Stdin []byte
- // Indicates that stdin should be closed.
- EOF bool
- // A dynamic update of the window size. The default value of 0 means no-change.
- Rows, Cols uint32
-}
-
-type ServerShellPacket struct {
- // Bytes coming from the shell's stdout.
- Stdout []byte
- // Bytes coming from the shell's stderr.
- Stderr []byte
-}
diff --git a/examples/tunnel/tunnel.vdl.go b/examples/tunnel/tunnel.vdl.go
deleted file mode 100644
index af5f436..0000000
--- a/examples/tunnel/tunnel.vdl.go
+++ /dev/null
@@ -1,729 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: tunnel.vdl
-
-package tunnel
-
-import (
- "veyron2/security"
-
- // The non-user imports are prefixed with "_gen_" to prevent collisions.
- _gen_io "io"
- _gen_veyron2 "veyron2"
- _gen_context "veyron2/context"
- _gen_ipc "veyron2/ipc"
- _gen_naming "veyron2/naming"
- _gen_vdlutil "veyron2/vdl/vdlutil"
- _gen_wiretype "veyron2/wiretype"
-)
-
-type ShellOpts struct {
- UsePty bool // Whether to open a pseudo-terminal
- Environment []string // Environment variables to pass to the remote shell.
- Rows uint32 // Window size.
- Cols uint32
-}
-
-type ClientShellPacket struct {
- // Bytes going to the shell's stdin.
- Stdin []byte
- // Indicates that stdin should be closed.
- EOF bool
- // A dynamic update of the window size. The default value of 0 means no-change.
- Rows uint32
- Cols uint32
-}
-
-type ServerShellPacket struct {
- // Bytes coming from the shell's stdout.
- Stdout []byte
- // Bytes coming from the shell's stderr.
- Stderr []byte
-}
-
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
-const _ = _gen_wiretype.TypeIDInvalid
-
-// Tunnel is the interface the client binds and uses.
-// Tunnel_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type Tunnel_ExcludingUniversal interface {
- // The Forward method is used for network forwarding. All the data sent over
- // the byte stream is forwarded to the requested network address and all the
- // data received from that network connection is sent back in the reply
- // stream.
- Forward(ctx _gen_context.T, network string, address string, opts ..._gen_ipc.CallOpt) (reply TunnelForwardCall, err error)
- // The Shell method is used to either run shell commands remotely, or to open
- // an interactive shell. The data received over the byte stream is sent to the
- // shell's stdin, and the data received from the shell's stdout and stderr is
- // sent back in the reply stream. It returns the exit status of the shell
- // command.
- Shell(ctx _gen_context.T, command string, shellOpts ShellOpts, opts ..._gen_ipc.CallOpt) (reply TunnelShellCall, err error)
-}
-type Tunnel interface {
- _gen_ipc.UniversalServiceMethods
- Tunnel_ExcludingUniversal
-}
-
-// TunnelService is the interface the server implements.
-type TunnelService interface {
-
- // The Forward method is used for network forwarding. All the data sent over
- // the byte stream is forwarded to the requested network address and all the
- // data received from that network connection is sent back in the reply
- // stream.
- Forward(context _gen_ipc.ServerContext, network string, address string, stream TunnelServiceForwardStream) (err error)
- // The Shell method is used to either run shell commands remotely, or to open
- // an interactive shell. The data received over the byte stream is sent to the
- // shell's stdin, and the data received from the shell's stdout and stderr is
- // sent back in the reply stream. It returns the exit status of the shell
- // command.
- Shell(context _gen_ipc.ServerContext, command string, shellOpts ShellOpts, stream TunnelServiceShellStream) (reply int32, err error)
-}
-
-// TunnelForwardCall is the interface for call object of the method
-// Forward in the service interface Tunnel.
-type TunnelForwardCall interface {
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() []byte
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-
- // SendStream returns the send portion of the stream
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no
- // buffer space available. Calls to Send after having called Close
- // or Cancel will fail. Any blocked Send calls will be unblocked upon
- // calling Cancel.
- Send(item []byte) error
-
- // Close indicates to the server that no more items will be sent;
- // server Recv calls will receive io.EOF after all sent items. This is
- // an optional call - it's used by streaming clients that need the
- // server to receive the io.EOF terminator before the client calls
- // Finish (for example, if the client needs to continue receiving items
- // from the server after having finished sending).
- // Calls to Close after having called Cancel will fail.
- // Like Send, Close blocks when there's no buffer space available.
- Close() error
- }
-
- // Finish performs the equivalent of SendStream().Close, then blocks until the server
- // is done, and returns the positional return values for call.
- // If Cancel has been called, Finish will return immediately; the output of
- // Finish could either be an error signalling cancelation, or the correct
- // positional return values from the server depending on the timing of the
- // call.
- //
- // Calling Finish is mandatory for releasing stream resources, unless Cancel
- // has been called or any of the other methods return an error.
- // Finish should be called at most once.
- Finish() (err error)
-
- // Cancel cancels the RPC, notifying the server to stop processing. It
- // is safe to call Cancel concurrently with any of the other stream methods.
- // Calling Cancel after Finish has returned is a no-op.
- Cancel()
-}
-
-type implTunnelForwardStreamSender struct {
- clientCall _gen_ipc.Call
-}
-
-func (c *implTunnelForwardStreamSender) Send(item []byte) error {
- return c.clientCall.Send(item)
-}
-
-func (c *implTunnelForwardStreamSender) Close() error {
- return c.clientCall.CloseSend()
-}
-
-type implTunnelForwardStreamIterator struct {
- clientCall _gen_ipc.Call
- val []byte
- err error
-}
-
-func (c *implTunnelForwardStreamIterator) Advance() bool {
- c.err = c.clientCall.Recv(&c.val)
- return c.err == nil
-}
-
-func (c *implTunnelForwardStreamIterator) Value() []byte {
- return c.val
-}
-
-func (c *implTunnelForwardStreamIterator) Err() error {
- if c.err == _gen_io.EOF {
- return nil
- }
- return c.err
-}
-
-// Implementation of the TunnelForwardCall interface that is not exported.
-type implTunnelForwardCall struct {
- clientCall _gen_ipc.Call
- writeStream implTunnelForwardStreamSender
- readStream implTunnelForwardStreamIterator
-}
-
-func (c *implTunnelForwardCall) SendStream() interface {
- Send(item []byte) error
- Close() error
-} {
- return &c.writeStream
-}
-
-func (c *implTunnelForwardCall) RecvStream() interface {
- Advance() bool
- Value() []byte
- Err() error
-} {
- return &c.readStream
-}
-
-func (c *implTunnelForwardCall) Finish() (err error) {
- if ierr := c.clientCall.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (c *implTunnelForwardCall) Cancel() {
- c.clientCall.Cancel()
-}
-
-type implTunnelServiceForwardStreamSender struct {
- serverCall _gen_ipc.ServerCall
-}
-
-func (s *implTunnelServiceForwardStreamSender) Send(item []byte) error {
- return s.serverCall.Send(item)
-}
-
-type implTunnelServiceForwardStreamIterator struct {
- serverCall _gen_ipc.ServerCall
- val []byte
- err error
-}
-
-func (s *implTunnelServiceForwardStreamIterator) Advance() bool {
- s.err = s.serverCall.Recv(&s.val)
- return s.err == nil
-}
-
-func (s *implTunnelServiceForwardStreamIterator) Value() []byte {
- return s.val
-}
-
-func (s *implTunnelServiceForwardStreamIterator) Err() error {
- if s.err == _gen_io.EOF {
- return nil
- }
- return s.err
-}
-
-// TunnelServiceForwardStream is the interface for streaming responses of the method
-// Forward in the service interface Tunnel.
-type TunnelServiceForwardStream interface {
- // SendStream returns the send portion of the stream.
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item []byte) error
- }
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() []byte
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-}
-
-// Implementation of the TunnelServiceForwardStream interface that is not exported.
-type implTunnelServiceForwardStream struct {
- writer implTunnelServiceForwardStreamSender
- reader implTunnelServiceForwardStreamIterator
-}
-
-func (s *implTunnelServiceForwardStream) SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item []byte) error
-} {
- return &s.writer
-}
-
-func (s *implTunnelServiceForwardStream) RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. The client must call Cancel if it does
- // not iterate through all elements (i.e. until Advance
- // returns false). Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() []byte
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
-} {
- return &s.reader
-}
-
-// TunnelShellCall is the interface for call object of the method
-// Shell in the service interface Tunnel.
-type TunnelShellCall interface {
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() ServerShellPacket
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-
- // SendStream returns the send portion of the stream
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no
- // buffer space available. Calls to Send after having called Close
- // or Cancel will fail. Any blocked Send calls will be unblocked upon
- // calling Cancel.
- Send(item ClientShellPacket) error
-
- // Close indicates to the server that no more items will be sent;
- // server Recv calls will receive io.EOF after all sent items. This is
- // an optional call - it's used by streaming clients that need the
- // server to receive the io.EOF terminator before the client calls
- // Finish (for example, if the client needs to continue receiving items
- // from the server after having finished sending).
- // Calls to Close after having called Cancel will fail.
- // Like Send, Close blocks when there's no buffer space available.
- Close() error
- }
-
- // Finish performs the equivalent of SendStream().Close, then blocks until the server
- // is done, and returns the positional return values for call.
- // If Cancel has been called, Finish will return immediately; the output of
- // Finish could either be an error signalling cancelation, or the correct
- // positional return values from the server depending on the timing of the
- // call.
- //
- // Calling Finish is mandatory for releasing stream resources, unless Cancel
- // has been called or any of the other methods return an error.
- // Finish should be called at most once.
- Finish() (reply int32, err error)
-
- // Cancel cancels the RPC, notifying the server to stop processing. It
- // is safe to call Cancel concurrently with any of the other stream methods.
- // Calling Cancel after Finish has returned is a no-op.
- Cancel()
-}
-
-type implTunnelShellStreamSender struct {
- clientCall _gen_ipc.Call
-}
-
-func (c *implTunnelShellStreamSender) Send(item ClientShellPacket) error {
- return c.clientCall.Send(item)
-}
-
-func (c *implTunnelShellStreamSender) Close() error {
- return c.clientCall.CloseSend()
-}
-
-type implTunnelShellStreamIterator struct {
- clientCall _gen_ipc.Call
- val ServerShellPacket
- err error
-}
-
-func (c *implTunnelShellStreamIterator) Advance() bool {
- c.val = ServerShellPacket{}
- c.err = c.clientCall.Recv(&c.val)
- return c.err == nil
-}
-
-func (c *implTunnelShellStreamIterator) Value() ServerShellPacket {
- return c.val
-}
-
-func (c *implTunnelShellStreamIterator) Err() error {
- if c.err == _gen_io.EOF {
- return nil
- }
- return c.err
-}
-
-// Implementation of the TunnelShellCall interface that is not exported.
-type implTunnelShellCall struct {
- clientCall _gen_ipc.Call
- writeStream implTunnelShellStreamSender
- readStream implTunnelShellStreamIterator
-}
-
-func (c *implTunnelShellCall) SendStream() interface {
- Send(item ClientShellPacket) error
- Close() error
-} {
- return &c.writeStream
-}
-
-func (c *implTunnelShellCall) RecvStream() interface {
- Advance() bool
- Value() ServerShellPacket
- Err() error
-} {
- return &c.readStream
-}
-
-func (c *implTunnelShellCall) Finish() (reply int32, err error) {
- if ierr := c.clientCall.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (c *implTunnelShellCall) Cancel() {
- c.clientCall.Cancel()
-}
-
-type implTunnelServiceShellStreamSender struct {
- serverCall _gen_ipc.ServerCall
-}
-
-func (s *implTunnelServiceShellStreamSender) Send(item ServerShellPacket) error {
- return s.serverCall.Send(item)
-}
-
-type implTunnelServiceShellStreamIterator struct {
- serverCall _gen_ipc.ServerCall
- val ClientShellPacket
- err error
-}
-
-func (s *implTunnelServiceShellStreamIterator) Advance() bool {
- s.val = ClientShellPacket{}
- s.err = s.serverCall.Recv(&s.val)
- return s.err == nil
-}
-
-func (s *implTunnelServiceShellStreamIterator) Value() ClientShellPacket {
- return s.val
-}
-
-func (s *implTunnelServiceShellStreamIterator) Err() error {
- if s.err == _gen_io.EOF {
- return nil
- }
- return s.err
-}
-
-// TunnelServiceShellStream is the interface for streaming responses of the method
-// Shell in the service interface Tunnel.
-type TunnelServiceShellStream interface {
- // SendStream returns the send portion of the stream.
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item ServerShellPacket) error
- }
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() ClientShellPacket
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-}
-
-// Implementation of the TunnelServiceShellStream interface that is not exported.
-type implTunnelServiceShellStream struct {
- writer implTunnelServiceShellStreamSender
- reader implTunnelServiceShellStreamIterator
-}
-
-func (s *implTunnelServiceShellStream) SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item ServerShellPacket) error
-} {
- return &s.writer
-}
-
-func (s *implTunnelServiceShellStream) RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. The client must call Cancel if it does
- // not iterate through all elements (i.e. until Advance
- // returns false). Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() ClientShellPacket
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
-} {
- return &s.reader
-}
-
-// BindTunnel returns the client stub implementing the Tunnel
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindTunnel(name string, opts ..._gen_ipc.BindOpt) (Tunnel, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubTunnel{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerTunnel creates a new server stub.
-//
-// It takes a regular server implementing the TunnelService
-// interface, and returns a new server stub.
-func NewServerTunnel(server TunnelService) interface{} {
- return &ServerStubTunnel{
- service: server,
- }
-}
-
-// clientStubTunnel implements Tunnel.
-type clientStubTunnel struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubTunnel) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubTunnel) Forward(ctx _gen_context.T, network string, address string, opts ..._gen_ipc.CallOpt) (reply TunnelForwardCall, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Forward", []interface{}{network, address}, opts...); err != nil {
- return
- }
- reply = &implTunnelForwardCall{clientCall: call, writeStream: implTunnelForwardStreamSender{clientCall: call}, readStream: implTunnelForwardStreamIterator{clientCall: call}}
- return
-}
-
-func (__gen_c *clientStubTunnel) Shell(ctx _gen_context.T, command string, shellOpts ShellOpts, opts ..._gen_ipc.CallOpt) (reply TunnelShellCall, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Shell", []interface{}{command, shellOpts}, opts...); err != nil {
- return
- }
- reply = &implTunnelShellCall{clientCall: call, writeStream: implTunnelShellStreamSender{clientCall: call}, readStream: implTunnelShellStreamIterator{clientCall: call}}
- return
-}
-
-func (__gen_c *clientStubTunnel) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubTunnel) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubTunnel) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubTunnel wraps a server that implements
-// TunnelService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubTunnel struct {
- service TunnelService
-}
-
-func (__gen_s *ServerStubTunnel) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Forward":
- return []interface{}{security.Label(8)}, nil
- case "Shell":
- return []interface{}{security.Label(8)}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubTunnel) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["Forward"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "network", Type: 3},
- {Name: "address", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- InStream: 67,
- OutStream: 67,
- }
- result.Methods["Shell"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "command", Type: 3},
- {Name: "shellOpts", Type: 68},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 36},
- {Name: "", Type: 65},
- },
- InStream: 69,
- OutStream: 70,
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x42, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x2, Name: "UsePty"},
- _gen_wiretype.FieldType{Type: 0x3d, Name: "Environment"},
- _gen_wiretype.FieldType{Type: 0x34, Name: "Rows"},
- _gen_wiretype.FieldType{Type: 0x34, Name: "Cols"},
- },
- "veyron/examples/tunnel.ShellOpts", []string(nil)},
- _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x43, Name: "Stdin"},
- _gen_wiretype.FieldType{Type: 0x2, Name: "EOF"},
- _gen_wiretype.FieldType{Type: 0x34, Name: "Rows"},
- _gen_wiretype.FieldType{Type: 0x34, Name: "Cols"},
- },
- "veyron/examples/tunnel.ClientShellPacket", []string(nil)},
- _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x43, Name: "Stdout"},
- _gen_wiretype.FieldType{Type: 0x43, Name: "Stderr"},
- },
- "veyron/examples/tunnel.ServerShellPacket", []string(nil)},
- }
-
- return result, nil
-}
-
-func (__gen_s *ServerStubTunnel) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubTunnel) Forward(call _gen_ipc.ServerCall, network string, address string) (err error) {
- stream := &implTunnelServiceForwardStream{reader: implTunnelServiceForwardStreamIterator{serverCall: call}, writer: implTunnelServiceForwardStreamSender{serverCall: call}}
- err = __gen_s.service.Forward(call, network, address, stream)
- return
-}
-
-func (__gen_s *ServerStubTunnel) Shell(call _gen_ipc.ServerCall, command string, shellOpts ShellOpts) (reply int32, err error) {
- stream := &implTunnelServiceShellStream{reader: implTunnelServiceShellStreamIterator{serverCall: call}, writer: implTunnelServiceShellStreamSender{serverCall: call}}
- reply, err = __gen_s.service.Shell(call, command, shellOpts, stream)
- return
-}
diff --git a/examples/tunnel/tunneld/impl/impl.go b/examples/tunnel/tunneld/impl/impl.go
deleted file mode 100644
index 32dd2f3..0000000
--- a/examples/tunnel/tunneld/impl/impl.go
+++ /dev/null
@@ -1,168 +0,0 @@
-package impl
-
-import (
- "github.com/kr/pty"
-
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "net"
- "os"
- "os/exec"
- "syscall"
-
- "veyron/examples/tunnel"
- "veyron/examples/tunnel/lib"
- "veyron2/ipc"
- "veyron2/vlog"
-)
-
-// T implements tunnel.TunnelService
-type T struct {
-}
-
-const nonShellErrorCode = 255
-
-func (t *T) Forward(ctx ipc.ServerContext, network, address string, stream tunnel.TunnelServiceForwardStream) error {
- conn, err := net.Dial(network, address)
- if err != nil {
- return err
- }
- name := fmt.Sprintf("RemoteID:%v LocalAddr:%v RemoteAddr:%v", ctx.RemoteID(), conn.LocalAddr(), conn.RemoteAddr())
- vlog.Infof("TUNNEL START: %v", name)
- err = lib.Forward(conn, stream.SendStream(), stream.RecvStream())
- vlog.Infof("TUNNEL END : %v (%v)", name, err)
- return err
-}
-
-func (t *T) Shell(ctx ipc.ServerContext, command string, shellOpts tunnel.ShellOpts, stream tunnel.TunnelServiceShellStream) (int32, error) {
- vlog.Infof("SHELL START for %v: %q", ctx.RemoteID(), command)
- shell, err := findShell()
- if err != nil {
- return nonShellErrorCode, err
- }
- var c *exec.Cmd
- // An empty command means that we need an interactive shell.
- if len(command) == 0 {
- c = exec.Command(shell, "-i")
- sendMotd(stream)
- } else {
- c = exec.Command(shell, "-c", command)
- }
-
- c.Env = []string{
- fmt.Sprintf("HOME=%s", os.Getenv("HOME")),
- fmt.Sprintf("VEYRON_LOCAL_IDENTITY=%s", ctx.LocalID()),
- fmt.Sprintf("VEYRON_REMOTE_IDENTITY=%s", ctx.RemoteID()),
- }
- c.Env = append(c.Env, shellOpts.Environment...)
- vlog.Infof("Shell environment: %v", c.Env)
-
- c.Dir = os.Getenv("HOME")
- vlog.Infof("Shell CWD: %v", c.Dir)
-
- var (
- stdin io.WriteCloser // We write to stdin.
- stdout, stderr io.ReadCloser // We read from stdout and stderr.
- ptyFd uintptr // File descriptor for pty.
- )
-
- if shellOpts.UsePty {
- f, err := pty.Start(c)
- if err != nil {
- return nonShellErrorCode, err
- }
- stdin = f
- stdout = f
- stderr = nil
- ptyFd = f.Fd()
-
- defer f.Close()
-
- setWindowSize(ptyFd, shellOpts.Rows, shellOpts.Cols)
- } else {
- var err error
- if stdin, err = c.StdinPipe(); err != nil {
- return nonShellErrorCode, err
- }
- defer stdin.Close()
-
- if stdout, err = c.StdoutPipe(); err != nil {
- return nonShellErrorCode, err
- }
- defer stdout.Close()
-
- if stderr, err = c.StderrPipe(); err != nil {
- return nonShellErrorCode, err
- }
- defer stderr.Close()
-
- if err = c.Start(); err != nil {
- vlog.Infof("Cmd.Start failed: %v", err)
- return nonShellErrorCode, err
- }
- }
-
- defer c.Process.Kill()
-
- select {
- case runErr := <-runIOManager(stdin, stdout, stderr, ptyFd, stream):
- vlog.Infof("SHELL END for %v: %q (%v)", ctx.RemoteID(), command, runErr)
- return harvestExitcode(c.Process, runErr)
- case <-ctx.Done():
- return nonShellErrorCode, fmt.Errorf("remote end exited")
- }
-}
-
-// harvestExitcode returns the (exitcode, error) pair to be returned for the Shell RPC
-// based on the status of the process and the error returned from runIOManager
-func harvestExitcode(process *os.Process, ioerr error) (int32, error) {
- // Check the exit status.
- var status syscall.WaitStatus
- if _, err := syscall.Wait4(process.Pid, &status, syscall.WNOHANG, nil); err != nil {
- return nonShellErrorCode, err
- }
- if status.Signaled() {
- return int32(status), fmt.Errorf("process killed by signal %u (%v)", status.Signal(), status.Signal())
- }
- if status.Exited() {
- if status.ExitStatus() == 0 {
- return 0, nil
- }
- return int32(status.ExitStatus()), fmt.Errorf("process exited with exit status %d", status.ExitStatus())
- }
- // The process has not exited. Use the error from ForwardStdIO.
- return nonShellErrorCode, ioerr
-}
-
-// findShell returns the path to the first usable shell binary.
-func findShell() (string, error) {
- shells := []string{"/bin/bash", "/bin/sh"}
- for _, s := range shells {
- if _, err := os.Stat(s); err == nil {
- return s, nil
- }
- }
- return "", errors.New("could not find any shell binary")
-}
-
-// sendMotd sends the content of the MOTD file to the stream, if it exists.
-func sendMotd(s tunnel.TunnelServiceShellStream) {
- data, err := ioutil.ReadFile("/etc/motd")
- if err != nil {
- // No MOTD. That's OK.
- return
- }
- packet := tunnel.ServerShellPacket{Stdout: []byte(data)}
- if err = s.SendStream().Send(packet); err != nil {
- vlog.Infof("Send failed: %v", err)
- }
-}
-
-func setWindowSize(fd uintptr, row, col uint32) {
- ws := lib.Winsize{Row: uint16(row), Col: uint16(col)}
- if err := lib.SetWindowSize(fd, ws); err != nil {
- vlog.Infof("Failed to set window size: %v", err)
- }
-}
diff --git a/examples/tunnel/tunneld/impl/iomanager.go b/examples/tunnel/tunneld/impl/iomanager.go
deleted file mode 100644
index aba419d..0000000
--- a/examples/tunnel/tunneld/impl/iomanager.go
+++ /dev/null
@@ -1,183 +0,0 @@
-package impl
-
-import (
- "fmt"
- "io"
- "sync"
-
- "veyron/examples/tunnel"
- "veyron2/vlog"
-)
-
-func runIOManager(stdin io.WriteCloser, stdout, stderr io.Reader, ptyFd uintptr, stream tunnel.TunnelServiceShellStream) <-chan error {
- m := ioManager{stdin: stdin, stdout: stdout, stderr: stderr, ptyFd: ptyFd, stream: stream}
- c := make(chan error, 1) // buffered channel so that the goroutine spawned below is not leaked if the channel is not read from.
- go func() { c <- m.run() }()
- return c
-}
-
-// ioManager manages the forwarding of all the data between the shell and the
-// stream.
-type ioManager struct {
- stdin io.WriteCloser
- stdout, stderr io.Reader
- ptyFd uintptr
- stream tunnel.TunnelServiceShellStream
-
- // streamError receives errors coming from stream operations.
- streamError chan error
- // stdioError receives errors coming from stdio operations.
- stdioError chan error
-}
-
-func (m *ioManager) run() error {
- m.streamError = make(chan error, 1)
- m.stdioError = make(chan error, 1)
-
- var pendingShellOutput sync.WaitGroup
- pendingShellOutput.Add(1)
- var pendingStreamInput sync.WaitGroup
- pendingStreamInput.Add(1)
-
- // Forward data between the shell's stdio and the stream.
- go func() {
- defer pendingShellOutput.Done()
- // outchan is used to serialize the output to the stream.
- // chan2stream() receives data sent by stdout2outchan() and
- // stderr2outchan() and sends it to the stream.
- outchan := make(chan tunnel.ServerShellPacket)
- var wgStream sync.WaitGroup
- wgStream.Add(1)
- go m.chan2stream(outchan, &wgStream)
- var wgStdio sync.WaitGroup
- wgStdio.Add(1)
- go m.stdout2outchan(outchan, &wgStdio)
- if m.stderr != nil {
- wgStdio.Add(1)
- go m.stderr2outchan(outchan, &wgStdio)
- }
- // When both stdout2outchan and stderr2outchan are done, close
- // outchan to signal chan2stream to exit.
- wgStdio.Wait()
- close(outchan)
- wgStream.Wait()
- }()
- go m.stream2stdin(&pendingStreamInput)
-
- // Block until something reports an error.
- //
- // If there is any stream error, we assume that both ends of the stream
- // have an error, e.g. if stream.Reader.Advance fails then
- // stream.Sender.Send will fail. We process any remaining input from
- // the stream and then return.
- //
- // If there is any stdio error, we assume all 3 io channels will fail
- // (if stdout.Read fails then stdin.Write and stderr.Read will also
- // fail). We process is remaining output from the shell and then
- // return.
- select {
- case err := <-m.streamError:
- // Process remaining input from the stream before exiting.
- vlog.VI(2).Infof("run stream error: %v", err)
- pendingStreamInput.Wait()
- return err
- case err := <-m.stdioError:
- // Process remaining output from the shell before exiting.
- vlog.VI(2).Infof("run stdio error: %v", err)
- pendingShellOutput.Wait()
- return err
- }
-}
-
-func (m *ioManager) sendStreamError(err error) {
- select {
- case m.streamError <- err:
- default:
- }
-}
-
-func (m *ioManager) sendStdioError(err error) {
- select {
- case m.stdioError <- err:
- default:
- }
-}
-
-// chan2stream receives ServerShellPacket from outchan and sends it to stream.
-func (m *ioManager) chan2stream(outchan <-chan tunnel.ServerShellPacket, wg *sync.WaitGroup) {
- defer wg.Done()
- sender := m.stream.SendStream()
- for packet := range outchan {
- vlog.VI(3).Infof("chan2stream packet: %+v", packet)
- if err := sender.Send(packet); err != nil {
- vlog.VI(2).Infof("chan2stream: %v", err)
- m.sendStreamError(err)
- }
- }
-}
-
-// stdout2stream reads data from the shell's stdout and sends it to the outchan.
-func (m *ioManager) stdout2outchan(outchan chan<- tunnel.ServerShellPacket, wg *sync.WaitGroup) {
- defer wg.Done()
- for {
- buf := make([]byte, 2048)
- n, err := m.stdout.Read(buf[:])
- if err != nil {
- vlog.VI(2).Infof("stdout2outchan: %v", err)
- m.sendStdioError(err)
- return
- }
- outchan <- tunnel.ServerShellPacket{Stdout: buf[:n]}
- }
-}
-
-// stderr2stream reads data from the shell's stderr and sends it to the outchan.
-func (m *ioManager) stderr2outchan(outchan chan<- tunnel.ServerShellPacket, wg *sync.WaitGroup) {
- defer wg.Done()
- for {
- buf := make([]byte, 2048)
- n, err := m.stderr.Read(buf[:])
- if err != nil {
- vlog.VI(2).Infof("stderr2outchan: %v", err)
- m.sendStdioError(err)
- return
- }
- outchan <- tunnel.ServerShellPacket{Stderr: buf[:n]}
- }
-}
-
-// stream2stdin reads data from the stream and sends it to the shell's stdin.
-func (m *ioManager) stream2stdin(wg *sync.WaitGroup) {
- defer wg.Done()
- rStream := m.stream.RecvStream()
- for rStream.Advance() {
- packet := rStream.Value()
- vlog.VI(3).Infof("stream2stdin packet: %+v", packet)
- if len(packet.Stdin) > 0 {
- if n, err := m.stdin.Write(packet.Stdin); n != len(packet.Stdin) || err != nil {
- m.sendStdioError(fmt.Errorf("stdin.Write returned (%d, %v) want (%d, nil)", n, err, len(packet.Stdin)))
- return
- }
- }
- if packet.EOF {
- if err := m.stdin.Close(); err != nil {
- m.sendStdioError(fmt.Errorf("stdin.Close: %v", err))
- return
- }
- }
- if packet.Rows > 0 && packet.Cols > 0 && m.ptyFd != 0 {
- setWindowSize(m.ptyFd, packet.Rows, packet.Cols)
- }
- }
-
- err := rStream.Err()
- if err == nil {
- err = io.EOF
- }
-
- vlog.VI(2).Infof("stream2stdin: %v", err)
- m.sendStreamError(err)
- if err := m.stdin.Close(); err != nil {
- m.sendStdioError(fmt.Errorf("stdin.Close: %v", err))
- }
-}
diff --git a/examples/tunnel/tunneld/main.go b/examples/tunnel/tunneld/main.go
deleted file mode 100644
index 7f66f11..0000000
--- a/examples/tunnel/tunneld/main.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package main
-
-import (
- "errors"
- "flag"
- "fmt"
- "net"
- "os"
- "strings"
-
- "veyron/examples/tunnel"
- "veyron/examples/tunnel/tunneld/impl"
- "veyron/lib/signals"
- sflag "veyron/security/flag"
- "veyron2/ipc"
- "veyron2/rt"
- "veyron2/vlog"
-)
-
-var (
- // TODO(rthellend): Remove the protocol and address flags when the config
- // manager is working.
- protocol = flag.String("protocol", "tcp", "protocol to listen on. For example, set to 'veyron' and set --address to the endpoint/name of a proxy to have this tunnel service proxied.")
- address = flag.String("address", ":0", "address to listen on")
-)
-
-// firstHardwareAddrInUse returns the hwaddr of the first network interface
-// that is up, excluding loopback.
-func firstHardwareAddrInUse() (string, error) {
- interfaces, err := net.Interfaces()
- if err != nil {
- return "", err
- }
- for _, i := range interfaces {
- if !strings.HasPrefix(i.Name, "lo") && i.Flags&net.FlagUp != 0 {
- name := i.HardwareAddr.String()
- if len(name) == 0 {
- continue
- }
- vlog.Infof("Using %q (from %v)", name, i.Name)
- return name, nil
- }
- }
- return "", errors.New("No usable network interfaces")
-}
-
-func main() {
- r := rt.Init()
- defer r.Cleanup()
- server, err := r.NewServer()
- if err != nil {
- vlog.Fatalf("NewServer failed: %v", err)
- }
- defer server.Stop()
-
- ep, err := server.Listen(*protocol, *address)
- if err != nil {
- vlog.Fatalf("Listen(%q, %q) failed: %v", *protocol, *address, err)
- }
- hwaddr, err := firstHardwareAddrInUse()
- if err != nil {
- vlog.Fatalf("Couldn't find a good hw address: %v", err)
- }
- hostname, err := os.Hostname()
- if err != nil {
- vlog.Fatalf("os.Hostname failed: %v", err)
- }
- // TODO(rthellend): This is not secure. We should use
- // rt.R().Product().ID() and the associated verification, when it is
- // ready.
- names := []string{
- fmt.Sprintf("tunnel/hostname/%s", hostname),
- fmt.Sprintf("tunnel/hwaddr/%s", hwaddr),
- fmt.Sprintf("tunnel/id/%s", rt.R().Identity().PublicID()),
- }
- dispatcher := ipc.LeafDispatcher(tunnel.NewServerTunnel(&impl.T{}), sflag.NewAuthorizerOrDie())
- published := false
- for _, n := range names {
- if err := server.Serve(n, dispatcher); err != nil {
- vlog.Infof("Serve(%v) failed: %v", n, err)
- continue
- }
- published = true
- }
- if !published {
- vlog.Fatalf("Failed to publish with any of %v", names)
- }
- vlog.Infof("Listening on endpoint /%s (published as %v)", ep, names)
- <-signals.ShutdownOnSignals()
-}
diff --git a/examples/tunnel/tunneld/test.sh b/examples/tunnel/tunneld/test.sh
deleted file mode 100755
index 3889c93..0000000
--- a/examples/tunnel/tunneld/test.sh
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/bin/bash
-
-# Test the tunneld binary
-#
-# This test starts a tunnel server and a mounttable server and then verifies
-# that vsh can run commands through it and that all the expected names are
-# in the mounttable.
-
-source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
-
-build() {
- local -r GO="${REPO_ROOT}/scripts/build/go"
- "${GO}" build veyron/examples/tunnel/tunneld || shell_test::fail "line ${LINENO}: failed to build tunneld"
- "${GO}" build veyron/examples/tunnel/vsh || shell_test::fail "line ${LINENO}: failed to build vsh"
- "${GO}" build veyron/services/mounttable/mounttabled || shell_test::fail "line ${LINENO}: failed to build mounttabled"
- "${GO}" build veyron/tools/mounttable || shell_test::fail "line ${LINENO}: failed to build mounttable"
- "${GO}" build veyron/tools/identity || shell_test::fail "line ${LINENO}: failed to build identity"
-}
-
-dumplogs() {
- for x in $*; do
- echo "-- $(basename "${x}") --"
- cat "${x}"
- done
-}
-
-main() {
- cd "${TMPDIR}"
- build
-
- # Start mounttabled and find its endpoint.
- local -r MTLOG="${TMPDIR}/mt.log"
- ./mounttabled --address=127.0.0.1:0 > "${MTLOG}" 2>&1 &
- for i in 1 2 3 4; do
- local EP=$(grep "Mount table service at:" "${MTLOG}" | sed -e 's/^.*endpoint: //')
- if [[ -n "${EP}" ]]; then
- break
- fi
- sleep 1
- done
- [[ -z "${EP}" ]] && shell_test::fail "line ${LINENO}: no mounttable server"
-
- # Generate an identity for the tunnel server and client
- local -r ID="${TMPDIR}/id"
- VEYRON_IDENTITY="" ./identity generate test >"${ID}"
-
- export NAMESPACE_ROOT="${EP}"
- export VEYRON_IDENTITY="${ID}"
-
- # Start tunneld and find its endpoint.
- local -r TUNLOG="${TMPDIR}/tunnel.log"
- ./tunneld --address=127.0.0.1:0 > "${TUNLOG}" 2>&1 &
- for i in 1 2 3 4; do
- local EP=$(grep "Listening on endpoint" "${TUNLOG}" | sed -e 's/^.*endpoint //' | awk '{print $1}')
- if [[ -n "${EP}" ]]; then
- break
- fi
- sleep 1
- done
- [[ -z "${EP}" ]] && shell_test::fail "line ${LINENO}: no tunnel server"
-
- # Run remote command with the endpoint.
- local -r VSHLOG="${TMPDIR}/vsh.log"
- local GOT=$(./vsh --logtostderr --v=1 "${EP}" echo HELLO ENDPOINT 2>"${VSHLOG}")
- local WANT="HELLO ENDPOINT"
-
- if [[ "${GOT}" != "${WANT}" ]]; then
- dumplogs "${VSHLOG}" "${TUNLOG}" "${MTLOG}"
- shell_test::fail "line ${LINENO}: unexpected output. Got ${GOT}, want ${WANT}"
- fi
-
- # Run remote command with the object name.
- GOT=$(./vsh --logtostderr --v=1 tunnel/id/test echo HELLO NAME 2>"${VSHLOG}")
- WANT="HELLO NAME"
-
- if [[ "${GOT}" != "${WANT}" ]]; then
- dumplogs "${VSHLOG}" "${TUNLOG}" "${MTLOG}"
- shell_test::fail "line ${LINENO}: unexpected output. Got ${GOT}, want ${WANT}"
- fi
-
- # Send input to remote command.
- echo "HELLO SERVER" | ./vsh --logtostderr --v=1 "${EP}" "cat > ${TMPDIR}/hello.txt" > "${VSHLOG}" 2>&1
- GOT=$(cat "${TMPDIR}/hello.txt")
- WANT="HELLO SERVER"
-
- if [[ "${GOT}" != "${WANT}" ]]; then
- dumplogs "${VSHLOG}" "${TUNLOG}" "${MTLOG}"
- shell_test::fail "line ${LINENO}: unexpected output. Got ${GOT}, want ${WANT}"
- fi
-
- GOT=$(echo "ECHO" | ./vsh --logtostderr --v=1 "${EP}" cat 2>"${VSHLOG}")
- WANT="ECHO"
-
- if [[ "${GOT}" != "${WANT}" ]]; then
- dumplogs "${VSHLOG}" "${TUNLOG}" "${MTLOG}"
- shell_test::fail "line ${LINENO}: unexpected output. Got ${GOT}, want ${WANT}"
- fi
-
- # Verify that all the published names are there.
- GOT=$(./mounttable glob "${NAMESPACE_ROOT}" 'tunnel/*/*' | \
- sed -e 's/TTL .m..s/TTL XmXXs/' \
- -e 's!hwaddr/[^ ]*!hwaddr/XX:XX:XX:XX:XX:XX!' | \
- sort)
- WANT="[${NAMESPACE_ROOT}]
-tunnel/hostname/$(hostname) ${EP}// (TTL XmXXs)
-tunnel/hwaddr/XX:XX:XX:XX:XX:XX ${EP}// (TTL XmXXs)
-tunnel/id/test ${EP}// (TTL XmXXs)"
-
- if [[ "${GOT}" != "${WANT}" ]]; then
- shell_test::fail "line ${LINENO}: unexpected output. Got ${GOT}, want ${WANT}"
- fi
-
- shell_test::pass
-}
-
-main "$@"
diff --git a/examples/tunnel/vsh/iomanager.go b/examples/tunnel/vsh/iomanager.go
deleted file mode 100644
index bc778d6..0000000
--- a/examples/tunnel/vsh/iomanager.go
+++ /dev/null
@@ -1,180 +0,0 @@
-package main
-
-import (
- "fmt"
- "io"
- "os"
- "os/signal"
- "sync"
- "syscall"
-
- "veyron/examples/tunnel"
- "veyron/examples/tunnel/lib"
- "veyron2/vlog"
-)
-
-func runIOManager(stdin io.Reader, stdout, stderr io.Writer, stream tunnel.TunnelShellCall) error {
- m := ioManager{stdin: stdin, stdout: stdout, stderr: stderr, stream: stream}
- return m.run()
-}
-
-// ioManager manages the forwarding of all the data between the shell and the
-// stream.
-type ioManager struct {
- stdin io.Reader
- stdout, stderr io.Writer
- stream tunnel.TunnelShellCall
-
- // streamError receives errors coming from stream operations.
- streamError chan error
- // stdioError receives errors coming from stdio operations.
- stdioError chan error
-}
-
-func (m *ioManager) run() error {
- m.streamError = make(chan error, 1)
- m.stdioError = make(chan error, 1)
-
- var pendingUserInput sync.WaitGroup
- pendingUserInput.Add(1)
- var pendingStreamOutput sync.WaitGroup
- pendingStreamOutput.Add(1)
-
- // Forward data between the user and the remote shell.
- go func() {
- defer pendingUserInput.Done()
- // outchan is used to serialize the output to the stream.
- // chan2stream() receives data sent by handleWindowResize() and
- // user2outchan() and sends it to the stream.
- outchan := make(chan tunnel.ClientShellPacket)
- var wgStream sync.WaitGroup
- wgStream.Add(1)
- go m.chan2stream(outchan, &wgStream)
-
- // When the terminal window is resized, we receive a SIGWINCH. Then we
- // send the new window size to the server.
- winch := make(chan os.Signal, 1)
- signal.Notify(winch, syscall.SIGWINCH)
-
- var wgUser sync.WaitGroup
- wgUser.Add(2)
- go func() {
- m.user2outchan(outchan, &wgUser)
- signal.Stop(winch)
- close(winch)
- }()
- go m.handleWindowResize(winch, outchan, &wgUser)
- // When both user2outchan and handleWindowResize are done,
- // close outchan to signal chan2stream to exit.
- wgUser.Wait()
- close(outchan)
- wgStream.Wait()
- }()
- go m.stream2user(&pendingStreamOutput)
- // Block until something reports an error.
- select {
- case err := <-m.streamError:
- // When we receive an error from the stream, wait for any
- // remaining stream output to be sent to the user before
- // exiting.
- vlog.VI(2).Infof("run stream error: %v", err)
- pendingStreamOutput.Wait()
- return err
- case err := <-m.stdioError:
- // When we receive an error from the user, wait for any
- // remaining input from the user to be sent to the stream
- // before exiting.
- vlog.VI(2).Infof("run stdio error: %v", err)
- pendingUserInput.Wait()
- return err
- }
-}
-
-func (m *ioManager) sendStreamError(err error) {
- select {
- case m.streamError <- err:
- default:
- }
-}
-
-func (m *ioManager) sendStdioError(err error) {
- select {
- case m.stdioError <- err:
- default:
- }
-}
-
-// chan2stream receives ClientShellPacket from outchan and sends it to stream.
-func (m *ioManager) chan2stream(outchan <-chan tunnel.ClientShellPacket, wg *sync.WaitGroup) {
- defer wg.Done()
- sender := m.stream.SendStream()
- for packet := range outchan {
- vlog.VI(3).Infof("chan2stream packet: %+v", packet)
- if err := sender.Send(packet); err != nil {
- vlog.VI(2).Infof("chan2stream: %v", err)
- m.sendStreamError(err)
- }
- }
- m.sendStreamError(io.EOF)
-}
-
-func (m *ioManager) handleWindowResize(winch <-chan os.Signal, outchan chan<- tunnel.ClientShellPacket, wg *sync.WaitGroup) {
- defer wg.Done()
- for _ = range winch {
- ws, err := lib.GetWindowSize()
- if err != nil {
- vlog.Infof("GetWindowSize failed: %v", err)
- continue
- }
- outchan <- tunnel.ClientShellPacket{Rows: uint32(ws.Row), Cols: uint32(ws.Col)}
- }
-}
-
-// user2stream reads input from stdin and sends it to the outchan.
-func (m *ioManager) user2outchan(outchan chan<- tunnel.ClientShellPacket, wg *sync.WaitGroup) {
- defer wg.Done()
- for {
- buf := make([]byte, 2048)
- n, err := m.stdin.Read(buf[:])
- if err == io.EOF {
- vlog.VI(2).Infof("user2outchan: EOF, closing stdin")
- outchan <- tunnel.ClientShellPacket{EOF: true}
- return
- }
- if err != nil {
- vlog.VI(2).Infof("user2outchan: %v", err)
- m.sendStdioError(err)
- return
- }
- outchan <- tunnel.ClientShellPacket{Stdin: buf[:n]}
- }
-}
-
-// stream2user reads data from the stream and sends it to either stdout or stderr.
-func (m *ioManager) stream2user(wg *sync.WaitGroup) {
- defer wg.Done()
- rStream := m.stream.RecvStream()
- for rStream.Advance() {
- packet := rStream.Value()
- vlog.VI(3).Infof("stream2user packet: %+v", packet)
-
- if len(packet.Stdout) > 0 {
- if n, err := m.stdout.Write(packet.Stdout); n != len(packet.Stdout) || err != nil {
- m.sendStdioError(fmt.Errorf("stdout.Write returned (%d, %v) want (%d, nil)", n, err, len(packet.Stdout)))
- return
- }
- }
- if len(packet.Stderr) > 0 {
- if n, err := m.stderr.Write(packet.Stderr); n != len(packet.Stderr) || err != nil {
- m.sendStdioError(fmt.Errorf("stderr.Write returned (%d, %v) want (%d, nil)", n, err, len(packet.Stderr)))
- return
- }
- }
- }
- err := rStream.Err()
- if err == nil {
- err = io.EOF
- }
- vlog.VI(2).Infof("stream2user: %v", err)
- m.sendStreamError(err)
-}
diff --git a/examples/tunnel/vsh/main.go b/examples/tunnel/vsh/main.go
deleted file mode 100644
index c6e958a..0000000
--- a/examples/tunnel/vsh/main.go
+++ /dev/null
@@ -1,211 +0,0 @@
-package main
-
-import (
- "errors"
- "flag"
- "fmt"
- "net"
- "os"
- "path"
- "strings"
- "time"
-
- "veyron/examples/tunnel"
- "veyron/examples/tunnel/lib"
- "veyron/lib/signals"
- "veyron2/context"
- "veyron2/rt"
- "veyron2/vlog"
-)
-
-var (
- disablePty = flag.Bool("T", false, "Disable pseudo-terminal allocation.")
- forcePty = flag.Bool("t", false, "Force allocation of pseudo-terminal.")
-
- portforward = flag.String("L", "", "localaddr,remoteaddr Forward local 'localaddr' to 'remoteaddr'")
- lprotocol = flag.String("local_protocol", "tcp", "Local network protocol for port forwarding")
- rprotocol = flag.String("remote_protocol", "tcp", "Remote network protocol for port forwarding")
-
- noshell = flag.Bool("N", false, "Do not execute a shell. Only do port forwarding.")
-)
-
-func init() {
- flag.Usage = func() {
- bname := path.Base(os.Args[0])
- fmt.Fprintf(os.Stderr, `%s: Veyron SHell.
-
-This tool is used to run shell commands or an interactive shell on a remote
-tunneld service.
-
-To open an interactive shell, use:
- %s <object name>
-
-To run a shell command, use:
- %s <object name> <command to run>
-
-The -L flag will forward connections from a local port to a remote address
-through the tunneld service. The flag value is localaddr,remoteaddr. E.g.
- -L :14141,www.google.com:80
-
-%s can't be used directly with tools like rsync because veyron object names
-don't look like traditional hostnames, which rsync doesn't understand. For
-compatibility with such tools, %s has a special feature that allows passing the
-veyron object name via the VSH_NAME environment variable.
-
- $ VSH_NAME=<object name> rsync -avh -e %s /foo/* veyron:/foo/
-
-In this example, the "veyron" host will be substituted with $VSH_NAME by %s
-and rsync will work as expected.
-
-Full flags:
-`, os.Args[0], bname, bname, bname, bname, os.Args[0], bname)
- flag.PrintDefaults()
- }
-}
-
-func main() {
- // Work around the fact that os.Exit doesn't run deferred functions.
- os.Exit(realMain())
-}
-
-func realMain() int {
- r := rt.Init()
- defer r.Cleanup()
-
- oname, cmd, err := objectNameAndCommandLine()
- if err != nil {
- flag.Usage()
- fmt.Fprintf(os.Stderr, "\n%v\n", err)
- return 1
- }
-
- t, err := tunnel.BindTunnel(oname)
- if err != nil {
- vlog.Fatalf("BindTunnel(%q) failed: %v", oname, err)
- }
-
- ctx, _ := rt.R().NewContext().WithTimeout(24 * time.Hour)
-
- if len(*portforward) > 0 {
- go runPortForwarding(ctx, t, oname)
- }
-
- if *noshell {
- <-signals.ShutdownOnSignals()
- return 0
- }
-
- opts := shellOptions(cmd)
-
- stream, err := t.Shell(ctx, cmd, opts)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error: %v\n", err)
- return 1
- }
- if opts.UsePty {
- saved := lib.EnterRawTerminalMode()
- defer lib.RestoreTerminalSettings(saved)
- }
- runIOManager(os.Stdin, os.Stdout, os.Stderr, stream)
-
- exitMsg := fmt.Sprintf("Connection to %s closed.", oname)
- exitStatus, err := stream.Finish()
- if err != nil {
- exitMsg += fmt.Sprintf(" (%v)", err)
- }
- vlog.VI(1).Info(exitMsg)
- // Only show the exit message on stdout for interactive shells.
- // Otherwise, the exit message might get confused with the output
- // of the command that was run.
- if err != nil {
- fmt.Fprintln(os.Stderr, exitMsg)
- } else if len(cmd) == 0 {
- fmt.Println(exitMsg)
- }
- return int(exitStatus)
-}
-
-func shellOptions(cmd string) (opts tunnel.ShellOpts) {
- opts.UsePty = (len(cmd) == 0 || *forcePty) && !*disablePty
- opts.Environment = environment()
- ws, err := lib.GetWindowSize()
- if err != nil {
- vlog.VI(1).Infof("GetWindowSize failed: %v", err)
- } else {
- opts.Rows = uint32(ws.Row)
- opts.Cols = uint32(ws.Col)
- }
- return
-}
-
-func environment() []string {
- env := []string{}
- for _, name := range []string{"TERM", "COLORTERM"} {
- if value := os.Getenv(name); value != "" {
- env = append(env, fmt.Sprintf("%s=%s", name, value))
- }
- }
- return env
-}
-
-// objectNameAndCommandLine extracts the object name and the remote command to
-// send to the server. The object name is the first non-flag argument.
-// The command line is the concatenation of all non-flag arguments excluding
-// the object name.
-func objectNameAndCommandLine() (string, string, error) {
- args := flag.Args()
- if len(args) < 1 {
- return "", "", errors.New("object name missing")
- }
- name := args[0]
- args = args[1:]
- // For compatibility with tools like rsync. Because object names
- // don't look like traditional hostnames, tools that work with rsh and
- // ssh can't work directly with vsh. This trick makes the following
- // possible:
- // $ VSH_NAME=<object name> rsync -avh -e vsh /foo/* veyron:/foo/
- // The "veyron" host will be substituted with <object name>.
- if envName := os.Getenv("VSH_NAME"); len(envName) > 0 && name == "veyron" {
- name = envName
- }
- cmd := strings.Join(args, " ")
- return name, cmd, nil
-}
-
-func runPortForwarding(ctx context.T, t tunnel.Tunnel, oname string) {
- // *portforward is localaddr,remoteaddr
- parts := strings.Split(*portforward, ",")
- var laddr, raddr string
- if len(parts) != 2 {
- vlog.Fatalf("-L flag expects 2 values separated by a comma")
- }
- laddr = parts[0]
- raddr = parts[1]
-
- ln, err := net.Listen(*lprotocol, laddr)
- if err != nil {
- vlog.Fatalf("net.Listen(%q, %q) failed: %v", *lprotocol, laddr, err)
- }
- defer ln.Close()
- vlog.VI(1).Infof("Listening on %q", ln.Addr())
- for {
- conn, err := ln.Accept()
- if err != nil {
- vlog.Infof("Accept failed: %v", err)
- continue
- }
- stream, err := t.Forward(ctx, *rprotocol, raddr)
- if err != nil {
- vlog.Infof("Tunnel(%q, %q) failed: %v", *rprotocol, raddr, err)
- conn.Close()
- continue
- }
- name := fmt.Sprintf("%v-->%v-->(%v)-->%v", conn.RemoteAddr(), conn.LocalAddr(), oname, raddr)
- go func() {
- vlog.VI(1).Infof("TUNNEL START: %v", name)
- errf := lib.Forward(conn, stream.SendStream(), stream.RecvStream())
- err := stream.Finish()
- vlog.VI(1).Infof("TUNNEL END : %v (%v, %v)", name, errf, err)
- }()
- }
-}
diff --git a/examples/unresolve/test_util.go b/examples/unresolve/test_util.go
deleted file mode 100644
index b4cfc18..0000000
--- a/examples/unresolve/test_util.go
+++ /dev/null
@@ -1,247 +0,0 @@
-package unresolve
-
-import (
- "fmt"
- "testing"
-
- "veyron2"
- "veyron2/context"
- "veyron2/ipc"
- "veyron2/naming"
- "veyron2/rt"
- "veyron2/security"
- mtidl "veyron2/services/mounttable"
- "veyron2/vlog"
-
- _ "veyron/lib/testutil"
- "veyron/lib/testutil/blackbox"
- mounttable "veyron/services/mounttable/lib"
-
- fortuneidl "veyron/examples/fortune"
-)
-
-func initRT(opts ...veyron2.ROpt) func() {
- return rt.Init(opts...).Cleanup
-}
-
-func createServer(name string, dispatcher ipc.Dispatcher, opts ...ipc.ServerOpt) (ipc.Server, string) {
- server, err := rt.R().NewServer(opts...)
- if err != nil {
- panic(fmt.Sprintf("r.NewServer failed with %v", err))
- }
- ep, err := server.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- panic(fmt.Sprintf("server.Listen failed with %v", err))
- }
- if err := server.Serve(name, dispatcher); err != nil {
- panic(fmt.Sprintf("server.Serve failed with %v", err))
- }
- oa := naming.JoinAddressName(ep.String(), "")
- vlog.Infof("created %s -> %s", name, oa)
- return server, oa
-}
-
-func childMT(args []string) {
- defer initRT()()
- for _, arg := range args {
- server, _ := createMTServer(arg)
- defer server.Stop()
- }
- fmt.Println("ready")
- blackbox.WaitForEOFOnStdin()
-}
-
-func createMTServer(mp string) (ipc.Server, string) {
- mt, err := mounttable.NewMountTable("")
- if err != nil {
- panic(fmt.Sprintf("NewMountTable failed with %v", err))
- }
- return createServer(mp, mt, veyron2.ServesMountTableOpt(true))
-}
-
-func createMTClient(name string) mtidl.MountTable {
- client, err := mtidl.BindMountTable(name)
- if err != nil {
- panic(fmt.Sprintf("BindMountTable failed with %v", err))
- }
- return client
-}
-
-const fixedFortuneMessage = "Sooner than you think, you will be deeply dissatisfied with a fortune."
-
-type fortune struct{}
-
-func (*fortune) Get(ipc.ServerContext) (string, error) {
- return fixedFortuneMessage, nil
-}
-
-func (*fortune) Add(ipc.ServerContext, string) error {
- return nil
-}
-
-func childFortune(args []string) {
- defer initRT()()
- server, _ := createServer(args[0], ipc.LeafDispatcher(fortuneidl.NewServerFortune(new(fortune)), nil))
- defer server.Stop()
- for _, arg := range args[1:] {
- server.Serve(arg, nil)
- }
- fmt.Println("ready")
- blackbox.WaitForEOFOnStdin()
-}
-
-type fortuneCustomUnresolve struct {
- custom string
-}
-
-func (*fortuneCustomUnresolve) Get(ipc.ServerContext) (string, error) {
- return fixedFortuneMessage, nil
-}
-
-func (*fortuneCustomUnresolve) Add(ipc.ServerContext, string) error {
- return nil
-}
-
-func (*fortuneCustomUnresolve) UnresolveStep(context ipc.ServerContext) ([]string, error) {
- servers, err := rt.R().Namespace().ResolveToMountTable(rt.R().NewContext(), "I/want/to/know")
- if err != nil {
- return nil, err
- }
- var reply []string
- for _, s := range servers {
- r := naming.MakeResolvable(s)
- reply = append(reply, naming.Join(r, "the/future"))
- }
- return reply, nil
-}
-
-// Can't use the LeafDispatcher since it doesn't allow name suffixes.
-type fortuned struct{ obj interface{} }
-
-func (f *fortuned) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
- return ipc.ReflectInvoker(f.obj), nil, nil
-}
-
-func createFortuneCustomUnresolve(mp string) (ipc.Server, string) {
- server, oa := createServer(mp, &fortuned{fortuneidl.NewServerFortune(new(fortuneCustomUnresolve))})
- rt.R().Namespace().Mount(rt.R().NewContext(), "I/want/to/know", oa+"//", 0)
- rt.R().Namespace().Mount(rt.R().NewContext(), "tell/me", oa+"//", 0)
- return server, oa
-}
-
-func childFortuneCustomUnresolve(args []string) {
- defer initRT()()
- for _, arg := range args {
- server, _ := createFortuneCustomUnresolve(arg)
- defer server.Stop()
- }
- fmt.Println("ready")
- blackbox.WaitForEOFOnStdin()
-}
-
-func childFortuneNoIDL(args []string) {
- defer initRT()()
- for _, arg := range args {
- server, _ := createServer(arg, ipc.LeafDispatcher(new(fortuneNoIDL), nil))
- defer server.Stop()
- }
- fmt.Println("ready")
- blackbox.WaitForEOFOnStdin()
-}
-
-func createFortuneClient(rt veyron2.Runtime, name string) fortuneidl.Fortune {
- client, err := fortuneidl.BindFortune(name, rt.Client())
- if err != nil {
- panic(fmt.Sprintf("BindFortune failed with %v", err))
- }
- return client
-}
-
-type fortuneNoIDL struct{}
-
-func (*fortuneNoIDL) Get(ipc.ServerCall) (string, error) {
- return fixedFortuneMessage, nil
-}
-
-func (*fortuneNoIDL) UnresolveStep(ipc.ServerCall) ([]string, error) {
- servers, err := rt.R().Namespace().ResolveToMountTable(rt.R().NewContext(), "g")
- if err != nil {
- return nil, err
- }
- var reply []string
- for _, s := range servers {
- r := naming.MakeResolvable(s)
- reply = append(reply, naming.Join(r, "fortune"))
- }
- return reply, nil
-}
-
-func resolveStep(t *testing.T, name string) string {
- client := createMTClient(name)
- results, suffix, err := client.ResolveStep(rt.R().NewContext())
- if err != nil {
- t.Errorf("ResolveStep on %q failed with %v", name, err)
- return ""
- }
- if len(results) != 1 {
- t.Errorf("Expected one result when resolving %q, got %q", name, results)
- return ""
- }
- return naming.Join(results[0].Server, suffix)
-}
-
-func resolve(t *testing.T, ns naming.Namespace, name string) string {
- results, err := ns.Resolve(rt.R().NewContext(), name)
- if err != nil {
- t.Errorf("Resolve failed with %v", err)
- return ""
- }
- if len(results) != 1 {
- t.Errorf("Expected one result when resolving %q, got %q", name, results)
- return ""
- }
- return results[0]
-}
-
-type unresolver interface {
- UnresolveStep(context.T, ...ipc.CallOpt) ([]string, error)
-}
-
-func unresolveStep(t *testing.T, ctx context.T, c unresolver) string {
- unres, err := c.UnresolveStep(ctx)
- if err != nil {
- t.Errorf("UnresolveStep failed with %v", err)
- return ""
- }
- if len(unres) != 1 {
- t.Errorf("c.UnresolveStep wanted 1 result, got: %q", unres)
- return ""
- }
- return unres[0]
-}
-
-func unresolve(t *testing.T, ns naming.Namespace, name string) string {
- results, err := ns.Unresolve(rt.R().NewContext(), name)
- if err != nil {
- t.Errorf("Unresolve failed with %v", err)
- return ""
- }
- if len(results) != 1 {
- t.Errorf("Expected one result when unresolving %q, got %q", name, results)
- return ""
- }
- return results[0]
-}
-
-func glob(t *testing.T, pattern string) []string {
- var replies []string
- rc, err := rt.R().Namespace().Glob(rt.R().NewContext(), pattern)
- if err != nil {
- t.Errorf("Glob(%s): err %v", pattern, err)
- return nil
- }
- for s := range rc {
- replies = append(replies, s.Name)
- }
- return replies
-}
diff --git a/examples/unresolve/unresolve_test.go b/examples/unresolve/unresolve_test.go
deleted file mode 100644
index 16826b0..0000000
--- a/examples/unresolve/unresolve_test.go
+++ /dev/null
@@ -1,326 +0,0 @@
-package unresolve
-
-import (
- "fmt"
- "os"
- "reflect"
- "testing"
-
- _ "veyron/lib/testutil"
- "veyron/lib/testutil/blackbox"
- "veyron/lib/testutil/security"
-
- "veyron2"
- "veyron2/naming"
- "veyron2/rt"
- "veyron2/vlog"
-)
-
-// The test sets up a topology of mounttables and servers (the latter configured
-// in various ways, with/without custom UnresolveStep methods, mounting
-// themselves with one or several names under a mounttable (directly or via
-// a name that resolves to a mounttable). The "ASCII" art below illustrates the
-// setup, with a description of each node in the topology following.
-//
-// (A)
-// |
-// |"b"
-// |
-// (B)
-// \_______________________________________________
-// | | | | | | |
-// |"c" |"d" | "I/want/to/know" |"e1" |"e2" |"f" |"g"
-// | | | "tell/me" | | | |
-// (C) (D) (D) (E) (E) (F) (G)
-//
-// A mounttable service (A) with OA "aEP" acting as a root mounttable.
-//
-// A mounttable service (B) with OA "bEP", mounting its ep "bEP" as "b" under
-// mounttable A.
-//
-// A fortune service (C) with OA "cEP", mounting its ep "cEP" as "c"
-// under mounttable B. [ This is the vanilla case. ]
-//
-// A fortune service (D) with OA "dEP", mounting its ep "dEP"
-// automatically as "d" under mounttable B, and also mounting the OA
-// "dEP" manually as "I/want/to/know" and "tell/me under mounttable B.
-// It implements its own custom UnresolveStep.
-// [ This demonstrates using a custom UnresolveStep implementation with
-// an IDL-based service. ]
-//
-// A fortune service (E) with OA "eEP", mounting its ep "eEP" as "e1"
-// and as "e2" under mounttable B. [ This shows a service published under more
-// than one name. ]
-//
-// A fortune service (F) with OA "fEP", with mounttable root "aOA/b/"
-// mounting its ep "fEP" as "f" under "aOA/b" (essentially, under mounttable
-// B). [ This shows a service whose local root is a name that resolves to a
-// mounttable via another mounttable (so local root is not just an OA ].
-// TODO(cnicolaou): move this case (multihop namespace root to the namespace
-// tests)
-//
-// A fortune service (G) with OA "gEP" that is not based on an IDL. G
-// mounts itself as "g" under mounttable B, and defines its own UnresolveStep.
-// [ This demonstrates defining UnresolveStep for a service that is not
-// IDL-based. ]
-//
-
-func TestHelperProcess(t *testing.T) {
- blackbox.HelperProcess(t)
-}
-
-func init() {
- blackbox.CommandTable["childMT"] = childMT
- blackbox.CommandTable["childFortune"] = childFortune
- blackbox.CommandTable["childFortuneCustomUnresolve"] = childFortuneCustomUnresolve
- blackbox.CommandTable["childFortuneNoIDL"] = childFortuneNoIDL
-}
-
-// TODO(caprita): Consider making shutdown part of blackbox.Child.
-func shutdown(child *blackbox.Child) {
- child.CloseStdin()
- child.ExpectEOFAndWait()
- child.Cleanup()
-}
-
-func TestUnresolve(t *testing.T) {
- // Create the set of servers and ensure that the right mounttables act
- // as namespace roots for each. We run all servers with an identity blessed
- // by the root mounttable's identity under the name "test", i.e., if <rootMT>
- // is the identity of the root mounttable then the servers run with the identity
- // <rootMT>/test.
- // TODO(ataly): Eventually we want to use the same identities the servers
- // would have if they were running in production.
- defer initRT()()
-
- // Create mounttable A.
- mtServer, aOA := createMTServer("")
- if len(aOA) == 0 {
- t.Fatalf("aOA is empty")
- }
- defer mtServer.Stop()
- rt.R().Namespace().SetRoots(aOA)
-
- // A's object addess, aOA, is /<address>
- vlog.Infof("aOA=%v", aOA)
-
- idA := rt.R().Identity()
- vlog.Infof("idA=%v", idA)
-
- // Create mounttable B.
- // Mounttable B uses A as a root, that is, Publish calls made for
- // services running in B will appear in A, as <suffix used in publish>
- b := blackbox.HelperCommand(t, "childMT", "b")
- defer shutdown(b)
-
- idFile := security.SaveIdentityToFile(security.NewBlessedIdentity(idA, "test"))
- defer os.Remove(idFile)
- b.Cmd.Env = append(b.Cmd.Env, fmt.Sprintf("VEYRON_IDENTITY=%v", idFile), fmt.Sprintf("NAMESPACE_ROOT=%v", aOA))
- b.Cmd.Start()
- b.Expect("ready")
-
- // We want to obtain the name for the MountTable mounted in A as b,
- // in particular, we want the OA of B's Mounttable service.
- // We do so by asking Mounttable A to resolve //b using its
- // ResolveStep method. The name (//b) has to be terminal since we are
- // invoking a methond on the MountTable rather asking the MountTable to
- // resolve the name!
- aName := naming.Join(aOA, "//b")
-
- bOA := resolveStep(t, aName)
- vlog.Infof("bOA=%v", bOA)
- bAddr, _ := naming.SplitAddressName(bOA)
-
- // Create server C.
- c := blackbox.HelperCommand(t, "childFortune", "c")
- defer shutdown(c)
- idFile = security.SaveIdentityToFile(security.NewBlessedIdentity(idA, "test"))
- defer os.Remove(idFile)
- c.Cmd.Env = append(c.Cmd.Env, fmt.Sprintf("VEYRON_IDENTITY=%v", idFile), fmt.Sprintf("NAMESPACE_ROOT=%v", bOA))
- c.Cmd.Start()
- c.Expect("ready")
- cEP := resolveStep(t, naming.Join(bOA, "//c"))
- vlog.Infof("cEP=%v", cEP)
-
- // Create server D and the fortune service with a custom unresolver
- d := blackbox.HelperCommand(t, "childFortuneCustomUnresolve", "d")
- defer shutdown(d)
- idFile = security.SaveIdentityToFile(security.NewBlessedIdentity(idA, "test"))
- defer os.Remove(idFile)
- d.Cmd.Env = append(d.Cmd.Env, fmt.Sprintf("VEYRON_IDENTITY=%v", idFile), fmt.Sprintf("NAMESPACE_ROOT=%v", bOA))
- d.Cmd.Start()
- d.Expect("ready")
- dEP := resolveStep(t, naming.Join(bOA, "//d"))
- vlog.Infof("dEP=%v", dEP)
-
- // Create server E.
- e := blackbox.HelperCommand(t, "childFortune", "e1", "e2")
- defer shutdown(e)
- idFile = security.SaveIdentityToFile(security.NewBlessedIdentity(idA, "test"))
- defer os.Remove(idFile)
- e.Cmd.Env = append(e.Cmd.Env, fmt.Sprintf("VEYRON_IDENTITY=%v", idFile), fmt.Sprintf("NAMESPACE_ROOT=%v", bOA))
- e.Cmd.Start()
- e.Expect("ready")
- eEP := resolveStep(t, naming.Join(bOA, "//e1"))
- vlog.Infof("eEP=%v", eEP)
-
- f := blackbox.HelperCommand(t, "childFortune", "f")
- defer shutdown(f)
- idFile = security.SaveIdentityToFile(security.NewBlessedIdentity(idA, "test"))
- defer os.Remove(idFile)
- f.Cmd.Env = append(f.Cmd.Env, fmt.Sprintf("VEYRON_IDENTITY=%v", idFile), fmt.Sprintf("NAMESPACE_ROOT=%v", naming.Join(aOA, "b")))
- f.Cmd.Start()
- f.Expect("ready")
- fEP := resolveStep(t, naming.JoinAddressName(bAddr, "//f"))
- vlog.Infof("fEP=%v", fEP)
-
- // Create server G.
- g := blackbox.HelperCommand(t, "childFortuneNoIDL", "g")
- defer shutdown(g)
- idFile = security.SaveIdentityToFile(security.NewBlessedIdentity(idA, "test"))
- defer os.Remove(idFile)
- g.Cmd.Env = append(g.Cmd.Env, fmt.Sprintf("VEYRON_IDENTITY=%v", idFile), fmt.Sprintf("NAMESPACE_ROOT=%v", bOA))
- g.Cmd.Start()
- g.Expect("ready")
- gEP := resolveStep(t, naming.Join(bOA, "//g"))
- vlog.Infof("gEP=%v", gEP)
-
- vlog.Infof("ls /... %v", glob(t, "..."))
-
- // Check that things resolve correctly.
-
- // Create a client runtime with oOA as its root.
- idFile = security.SaveIdentityToFile(security.NewBlessedIdentity(idA, "test"))
- defer os.Remove(idFile)
- os.Setenv("VEYRON_IDENTITY", idFile)
-
- r, _ := rt.New(veyron2.NamespaceRoots([]string{aOA}))
- ctx := r.NewContext()
-
- resolveCases := []struct {
- name, resolved string
- }{
- {"b/c", cEP},
- {"b/d", dEP},
- {"b/I/want/to/know", dEP},
- {"b/tell/me/the/future", naming.Join(dEP, "the/future")},
- {"b/e1", eEP},
- {"b/e2", eEP},
- {"b/g", gEP},
- }
- for _, c := range resolveCases {
- if want, got := c.resolved, resolve(t, r.Namespace(), c.name); want != got {
- t.Errorf("resolve %q expected %q, got %q instead", c.name, want, got)
- }
- }
-
- // Verify that we can talk to the servers we created, and that unresolve
- // one step at a time works.
- unresolveStepCases := []struct {
- name, unresStep1, unresStep2 string
- }{
- {
- "b/c",
- naming.Join(bOA, "c"),
- naming.Join(aOA, "b/c"),
- },
- {
- "b/tell/me",
- naming.Join(bOA, "I/want/to/know/the/future"),
- naming.Join(aOA, "b/I/want/to/know/the/future"),
- },
- {
- "b/f",
- naming.Join(bOA, "f"),
- naming.Join(aOA, "b/f"),
- },
- {
- "b/g",
- naming.Join(bOA, "g/fortune"),
- naming.Join(aOA, "b/g/fortune"),
- },
- }
- for _, c := range unresolveStepCases {
- // Verify that we can talk to the server.
- client := createFortuneClient(r, c.name)
- if fortuneMessage, err := client.Get(r.NewContext()); err != nil {
- t.Errorf("fortune.Get: %s failed with %v", c.name, err)
- } else if fortuneMessage != fixedFortuneMessage {
- t.Errorf("fortune expected %q, got %q instead", fixedFortuneMessage, fortuneMessage)
- }
-
- // Unresolve, one step.
- if want, got := c.unresStep1, unresolveStep(t, ctx, client); want != got {
- t.Errorf("fortune.UnresolveStep expected %q, got %q instead", want, got)
- }
-
- // Go up the tree, unresolve another step.
- if want, got := c.unresStep2, unresolveStep(t, ctx, createMTClient(naming.MakeTerminal(c.unresStep1))); want != got {
- t.Errorf("mt.UnresolveStep expected %q, got %q instead", want, got)
- }
- }
-
- // We handle (E) separately since its UnresolveStep returns two names
- // instead of one.
-
- // Verify that we can talk to server E.
- eClient := createFortuneClient(r, "b/e1")
- if fortuneMessage, err := eClient.Get(ctx); err != nil {
- t.Errorf("fortune.Get failed with %v", err)
- } else if fortuneMessage != fixedFortuneMessage {
- t.Errorf("fortune expected %q, got %q instead", fixedFortuneMessage, fortuneMessage)
- }
-
- // Unresolve E, one step.
- eUnres, err := eClient.UnresolveStep(ctx)
- if err != nil {
- t.Errorf("UnresolveStep failed with %v", err)
- }
- if want, got := []string{naming.Join(bOA, "e1"), naming.Join(bOA, "e2")}, eUnres; !reflect.DeepEqual(want, got) {
- t.Errorf("e.UnresolveStep expected %q, got %q instead", want, got)
- }
-
- // Try unresolve step on a random name in B.
- if want, got := naming.Join(aOA, "b/some/random/name"),
- unresolveStep(t, ctx, createMTClient(naming.Join(bOA, "//some/random/name"))); want != got {
- t.Errorf("b.UnresolveStep expected %q, got %q instead", want, got)
- }
-
- // Try unresolve step on a random name in A.
- if unres, err := createMTClient(naming.Join(aOA, "//another/random/name")).UnresolveStep(ctx); err != nil {
- t.Errorf("UnresolveStep failed with %v", err)
- } else if len(unres) > 0 {
- t.Errorf("b.UnresolveStep expected no results, got %q instead", unres)
- }
-
- // Verify that full unresolve works.
- unresolveCases := []struct {
- name, want string
- }{
- {"b/c", naming.Join(aOA, "b/c")},
- {naming.Join(bOA, "c"), naming.Join(aOA, "b/c")},
- {naming.Join(cEP, ""), naming.Join(aOA, "b/c")},
-
- {"b/tell/me/the/future", naming.Join(aOA, "b/I/want/to/know/the/future")},
- {"b/I/want/to/know/the/future", naming.Join(aOA, "b/I/want/to/know/the/future")},
- {naming.Join(bOA, "d/tell/me/the/future"), naming.Join(aOA, "b/I/want/to/know/the/future")},
-
- {naming.Join(bOA, "I/want/to/know/the/future"), naming.Join(aOA, "b/I/want/to/know/the/future")},
- {naming.Join(dEP, "tell/me/the/future"), naming.Join(aOA, "b/I/want/to/know/the/future")},
-
- {"b/e1", naming.Join(aOA, "b/e1")},
- {"b/e2", naming.Join(aOA, "b/e1")},
-
- {"b/f", naming.Join(aOA, "b/f")},
- {naming.Join(fEP, ""), naming.Join(aOA, "b/f")},
-
- {"b/g", naming.Join(aOA, "b/g/fortune")},
- {naming.Join(bOA, "g"), naming.Join(aOA, "b/g/fortune")},
- {naming.Join(gEP, ""), naming.Join(aOA, "b/g/fortune")},
- }
- for _, c := range unresolveCases {
- if want, got := c.want, unresolve(t, r.Namespace(), c.name); want != got {
- t.Errorf("unresolve %q expected %q, got %q instead", c.name, want, got)
- }
- }
-}
diff --git a/examples/wspr_sample/cache.vdl b/examples/wspr_sample/cache.vdl
deleted file mode 100644
index 8d86471..0000000
--- a/examples/wspr_sample/cache.vdl
+++ /dev/null
@@ -1,59 +0,0 @@
-package sample
-
-// A Cache service mimics the memcache interface.
-type Cache interface {
- // Set sets a value for a key.
- Set(key string, value any) error
-
- // Get returns the value for a key. If the value is not found, returns
- // a not found error.
- Get(key string) (any, error)
-
- // Same as Get, but casts the return argument to an byte.
- GetAsByte(key string) (byte, error)
- // Same as Get, but casts the return argument to an int32.
- GetAsInt32(key string) (int32, error)
- // Same as Get, but casts the return argument to an int64.
- GetAsInt64(key string) (int64, error)
- // Same as Get, but casts the return argument to an uint32.
- GetAsUint32(key string) (uint32, error)
- // Same as Get, but casts the return argument to an uint64.
- GetAsUint64(key string) (uint64, error)
- // Same as Get, but casts the return argument to an float32.
- GetAsFloat32(key string) (float32, error)
- // Same as Get, but casts the return argument to an float64.
- GetAsFloat64(key string) (float64, error)
- // Same as Get, but casts the return argument to a string.
- GetAsString(key string) (string, error)
- // Same as Get, but casts the return argument to a bool.
- GetAsBool(key string) (bool, error)
- // Same as Get, but casts the return argument to an error.
- GetAsError(key string) (error, error)
-
- // AsMap returns the full contents of the cache as a map.
- AsMap() (map[string]any, error)
-
- // KeyValuePairs returns the full contents of the cache as a slice of pairs.
- KeyValuePairs() ([]KeyValuePair, error)
-
- // MostRecentSet returns the key and value and the timestamp for the most
- // recent set operation
- // TODO(bprosnitz) support type types and change time to native time type
- MostRecentSet() (value KeyValuePair, time int64, err error)
-
- // KeyPage indexes into the keys (in alphanumerically sorted order) and
- // returns the indexth page of 10 keys.
- KeyPage(index int64) ([10]string, error)
-
- // Size returns the total number of entries in the cache.
- Size() (int64, error)
-
- // MultiGet sets up a stream that allows fetching multiple keys.
- MultiGet() stream<string, any> error
-}
-
-// KeyValuePair is a representation of a cached key and value pair.
-type KeyValuePair struct {
- Key string
- Value any
-}
diff --git a/examples/wspr_sample/cache.vdl.go b/examples/wspr_sample/cache.vdl.go
deleted file mode 100644
index 175ec24..0000000
--- a/examples/wspr_sample/cache.vdl.go
+++ /dev/null
@@ -1,950 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: cache.vdl
-
-package sample
-
-import (
- // The non-user imports are prefixed with "_gen_" to prevent collisions.
- _gen_io "io"
- _gen_veyron2 "veyron2"
- _gen_context "veyron2/context"
- _gen_ipc "veyron2/ipc"
- _gen_naming "veyron2/naming"
- _gen_vdlutil "veyron2/vdl/vdlutil"
- _gen_wiretype "veyron2/wiretype"
-)
-
-// KeyValuePair is a representation of a cached key and value pair.
-type KeyValuePair struct {
- Key string
- Value _gen_vdlutil.Any
-}
-
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
-const _ = _gen_wiretype.TypeIDInvalid
-
-// A Cache service mimics the memcache interface.
-// Cache is the interface the client binds and uses.
-// Cache_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type Cache_ExcludingUniversal interface {
- // Set sets a value for a key.
- Set(ctx _gen_context.T, key string, value _gen_vdlutil.Any, opts ..._gen_ipc.CallOpt) (err error)
- // Get returns the value for a key. If the value is not found, returns
- // a not found error.
- Get(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply _gen_vdlutil.Any, err error)
- // Same as Get, but casts the return argument to an byte.
- GetAsByte(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply byte, err error)
- // Same as Get, but casts the return argument to an int32.
- GetAsInt32(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply int32, err error)
- // Same as Get, but casts the return argument to an int64.
- GetAsInt64(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply int64, err error)
- // Same as Get, but casts the return argument to an uint32.
- GetAsUint32(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply uint32, err error)
- // Same as Get, but casts the return argument to an uint64.
- GetAsUint64(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply uint64, err error)
- // Same as Get, but casts the return argument to an float32.
- GetAsFloat32(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply float32, err error)
- // Same as Get, but casts the return argument to an float64.
- GetAsFloat64(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply float64, err error)
- // Same as Get, but casts the return argument to a string.
- GetAsString(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply string, err error)
- // Same as Get, but casts the return argument to a bool.
- GetAsBool(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply bool, err error)
- // Same as Get, but casts the return argument to an error.
- GetAsError(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply error, err error)
- // AsMap returns the full contents of the cache as a map.
- AsMap(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply map[string]_gen_vdlutil.Any, err error)
- // KeyValuePairs returns the full contents of the cache as a slice of pairs.
- KeyValuePairs(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []KeyValuePair, err error)
- // MostRecentSet returns the key and value and the timestamp for the most
- // recent set operation
- // TODO(bprosnitz) support type types and change time to native time type
- MostRecentSet(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (value KeyValuePair, time int64, err error)
- // KeyPage indexes into the keys (in alphanumerically sorted order) and
- // returns the indexth page of 10 keys.
- KeyPage(ctx _gen_context.T, index int64, opts ..._gen_ipc.CallOpt) (reply [10]string, err error)
- // Size returns the total number of entries in the cache.
- Size(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply int64, err error)
- // MultiGet sets up a stream that allows fetching multiple keys.
- MultiGet(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply CacheMultiGetCall, err error)
-}
-type Cache interface {
- _gen_ipc.UniversalServiceMethods
- Cache_ExcludingUniversal
-}
-
-// CacheService is the interface the server implements.
-type CacheService interface {
-
- // Set sets a value for a key.
- Set(context _gen_ipc.ServerContext, key string, value _gen_vdlutil.Any) (err error)
- // Get returns the value for a key. If the value is not found, returns
- // a not found error.
- Get(context _gen_ipc.ServerContext, key string) (reply _gen_vdlutil.Any, err error)
- // Same as Get, but casts the return argument to an byte.
- GetAsByte(context _gen_ipc.ServerContext, key string) (reply byte, err error)
- // Same as Get, but casts the return argument to an int32.
- GetAsInt32(context _gen_ipc.ServerContext, key string) (reply int32, err error)
- // Same as Get, but casts the return argument to an int64.
- GetAsInt64(context _gen_ipc.ServerContext, key string) (reply int64, err error)
- // Same as Get, but casts the return argument to an uint32.
- GetAsUint32(context _gen_ipc.ServerContext, key string) (reply uint32, err error)
- // Same as Get, but casts the return argument to an uint64.
- GetAsUint64(context _gen_ipc.ServerContext, key string) (reply uint64, err error)
- // Same as Get, but casts the return argument to an float32.
- GetAsFloat32(context _gen_ipc.ServerContext, key string) (reply float32, err error)
- // Same as Get, but casts the return argument to an float64.
- GetAsFloat64(context _gen_ipc.ServerContext, key string) (reply float64, err error)
- // Same as Get, but casts the return argument to a string.
- GetAsString(context _gen_ipc.ServerContext, key string) (reply string, err error)
- // Same as Get, but casts the return argument to a bool.
- GetAsBool(context _gen_ipc.ServerContext, key string) (reply bool, err error)
- // Same as Get, but casts the return argument to an error.
- GetAsError(context _gen_ipc.ServerContext, key string) (reply error, err error)
- // AsMap returns the full contents of the cache as a map.
- AsMap(context _gen_ipc.ServerContext) (reply map[string]_gen_vdlutil.Any, err error)
- // KeyValuePairs returns the full contents of the cache as a slice of pairs.
- KeyValuePairs(context _gen_ipc.ServerContext) (reply []KeyValuePair, err error)
- // MostRecentSet returns the key and value and the timestamp for the most
- // recent set operation
- // TODO(bprosnitz) support type types and change time to native time type
- MostRecentSet(context _gen_ipc.ServerContext) (value KeyValuePair, time int64, err error)
- // KeyPage indexes into the keys (in alphanumerically sorted order) and
- // returns the indexth page of 10 keys.
- KeyPage(context _gen_ipc.ServerContext, index int64) (reply [10]string, err error)
- // Size returns the total number of entries in the cache.
- Size(context _gen_ipc.ServerContext) (reply int64, err error)
- // MultiGet sets up a stream that allows fetching multiple keys.
- MultiGet(context _gen_ipc.ServerContext, stream CacheServiceMultiGetStream) (err error)
-}
-
-// CacheMultiGetCall is the interface for call object of the method
-// MultiGet in the service interface Cache.
-type CacheMultiGetCall interface {
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() _gen_vdlutil.Any
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-
- // SendStream returns the send portion of the stream
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no
- // buffer space available. Calls to Send after having called Close
- // or Cancel will fail. Any blocked Send calls will be unblocked upon
- // calling Cancel.
- Send(item string) error
-
- // Close indicates to the server that no more items will be sent;
- // server Recv calls will receive io.EOF after all sent items. This is
- // an optional call - it's used by streaming clients that need the
- // server to receive the io.EOF terminator before the client calls
- // Finish (for example, if the client needs to continue receiving items
- // from the server after having finished sending).
- // Calls to Close after having called Cancel will fail.
- // Like Send, Close blocks when there's no buffer space available.
- Close() error
- }
-
- // Finish performs the equivalent of SendStream().Close, then blocks until the server
- // is done, and returns the positional return values for call.
- // If Cancel has been called, Finish will return immediately; the output of
- // Finish could either be an error signalling cancelation, or the correct
- // positional return values from the server depending on the timing of the
- // call.
- //
- // Calling Finish is mandatory for releasing stream resources, unless Cancel
- // has been called or any of the other methods return an error.
- // Finish should be called at most once.
- Finish() (err error)
-
- // Cancel cancels the RPC, notifying the server to stop processing. It
- // is safe to call Cancel concurrently with any of the other stream methods.
- // Calling Cancel after Finish has returned is a no-op.
- Cancel()
-}
-
-type implCacheMultiGetStreamSender struct {
- clientCall _gen_ipc.Call
-}
-
-func (c *implCacheMultiGetStreamSender) Send(item string) error {
- return c.clientCall.Send(item)
-}
-
-func (c *implCacheMultiGetStreamSender) Close() error {
- return c.clientCall.CloseSend()
-}
-
-type implCacheMultiGetStreamIterator struct {
- clientCall _gen_ipc.Call
- val _gen_vdlutil.Any
- err error
-}
-
-func (c *implCacheMultiGetStreamIterator) Advance() bool {
- c.val = nil
- c.err = c.clientCall.Recv(&c.val)
- return c.err == nil
-}
-
-func (c *implCacheMultiGetStreamIterator) Value() _gen_vdlutil.Any {
- return c.val
-}
-
-func (c *implCacheMultiGetStreamIterator) Err() error {
- if c.err == _gen_io.EOF {
- return nil
- }
- return c.err
-}
-
-// Implementation of the CacheMultiGetCall interface that is not exported.
-type implCacheMultiGetCall struct {
- clientCall _gen_ipc.Call
- writeStream implCacheMultiGetStreamSender
- readStream implCacheMultiGetStreamIterator
-}
-
-func (c *implCacheMultiGetCall) SendStream() interface {
- Send(item string) error
- Close() error
-} {
- return &c.writeStream
-}
-
-func (c *implCacheMultiGetCall) RecvStream() interface {
- Advance() bool
- Value() _gen_vdlutil.Any
- Err() error
-} {
- return &c.readStream
-}
-
-func (c *implCacheMultiGetCall) Finish() (err error) {
- if ierr := c.clientCall.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (c *implCacheMultiGetCall) Cancel() {
- c.clientCall.Cancel()
-}
-
-type implCacheServiceMultiGetStreamSender struct {
- serverCall _gen_ipc.ServerCall
-}
-
-func (s *implCacheServiceMultiGetStreamSender) Send(item _gen_vdlutil.Any) error {
- return s.serverCall.Send(item)
-}
-
-type implCacheServiceMultiGetStreamIterator struct {
- serverCall _gen_ipc.ServerCall
- val string
- err error
-}
-
-func (s *implCacheServiceMultiGetStreamIterator) Advance() bool {
- s.err = s.serverCall.Recv(&s.val)
- return s.err == nil
-}
-
-func (s *implCacheServiceMultiGetStreamIterator) Value() string {
- return s.val
-}
-
-func (s *implCacheServiceMultiGetStreamIterator) Err() error {
- if s.err == _gen_io.EOF {
- return nil
- }
- return s.err
-}
-
-// CacheServiceMultiGetStream is the interface for streaming responses of the method
-// MultiGet in the service interface Cache.
-type CacheServiceMultiGetStream interface {
- // SendStream returns the send portion of the stream.
- SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item _gen_vdlutil.Any) error
- }
- // RecvStream returns the recv portion of the stream
- RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() string
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
- }
-}
-
-// Implementation of the CacheServiceMultiGetStream interface that is not exported.
-type implCacheServiceMultiGetStream struct {
- writer implCacheServiceMultiGetStreamSender
- reader implCacheServiceMultiGetStreamIterator
-}
-
-func (s *implCacheServiceMultiGetStream) SendStream() interface {
- // Send places the item onto the output stream, blocking if there is no buffer
- // space available. If the client has canceled, an error is returned.
- Send(item _gen_vdlutil.Any) error
-} {
- return &s.writer
-}
-
-func (s *implCacheServiceMultiGetStream) RecvStream() interface {
- // Advance stages an element so the client can retrieve it
- // with Value. Advance returns true iff there is an
- // element to retrieve. The client must call Advance before
- // calling Value. The client must call Cancel if it does
- // not iterate through all elements (i.e. until Advance
- // returns false). Advance may block if an element is not
- // immediately available.
- Advance() bool
-
- // Value returns the element that was staged by Advance.
- // Value may panic if Advance returned false or was not
- // called at all. Value does not block.
- Value() string
-
- // Err returns a non-nil error iff the stream encountered
- // any errors. Err does not block.
- Err() error
-} {
- return &s.reader
-}
-
-// BindCache returns the client stub implementing the Cache
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindCache(name string, opts ..._gen_ipc.BindOpt) (Cache, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubCache{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerCache creates a new server stub.
-//
-// It takes a regular server implementing the CacheService
-// interface, and returns a new server stub.
-func NewServerCache(server CacheService) interface{} {
- return &ServerStubCache{
- service: server,
- }
-}
-
-// clientStubCache implements Cache.
-type clientStubCache struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubCache) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubCache) Set(ctx _gen_context.T, key string, value _gen_vdlutil.Any, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Set", []interface{}{key, value}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) Get(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply _gen_vdlutil.Any, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Get", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetAsByte(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply byte, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetAsByte", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetAsInt32(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply int32, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetAsInt32", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetAsInt64(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply int64, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetAsInt64", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetAsUint32(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply uint32, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetAsUint32", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetAsUint64(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply uint64, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetAsUint64", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetAsFloat32(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply float32, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetAsFloat32", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetAsFloat64(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply float64, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetAsFloat64", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetAsString(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetAsString", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetAsBool(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply bool, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetAsBool", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetAsError(ctx _gen_context.T, key string, opts ..._gen_ipc.CallOpt) (reply error, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetAsError", []interface{}{key}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) AsMap(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply map[string]_gen_vdlutil.Any, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "AsMap", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) KeyValuePairs(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []KeyValuePair, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "KeyValuePairs", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) MostRecentSet(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (value KeyValuePair, time int64, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "MostRecentSet", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&value, &time, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) KeyPage(ctx _gen_context.T, index int64, opts ..._gen_ipc.CallOpt) (reply [10]string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "KeyPage", []interface{}{index}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) Size(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply int64, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Size", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) MultiGet(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply CacheMultiGetCall, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "MultiGet", nil, opts...); err != nil {
- return
- }
- reply = &implCacheMultiGetCall{clientCall: call, writeStream: implCacheMultiGetStreamSender{clientCall: call}, readStream: implCacheMultiGetStreamIterator{clientCall: call}}
- return
-}
-
-func (__gen_c *clientStubCache) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubCache) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubCache wraps a server that implements
-// CacheService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubCache struct {
- service CacheService
-}
-
-func (__gen_s *ServerStubCache) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "Set":
- return []interface{}{}, nil
- case "Get":
- return []interface{}{}, nil
- case "GetAsByte":
- return []interface{}{}, nil
- case "GetAsInt32":
- return []interface{}{}, nil
- case "GetAsInt64":
- return []interface{}{}, nil
- case "GetAsUint32":
- return []interface{}{}, nil
- case "GetAsUint64":
- return []interface{}{}, nil
- case "GetAsFloat32":
- return []interface{}{}, nil
- case "GetAsFloat64":
- return []interface{}{}, nil
- case "GetAsString":
- return []interface{}{}, nil
- case "GetAsBool":
- return []interface{}{}, nil
- case "GetAsError":
- return []interface{}{}, nil
- case "AsMap":
- return []interface{}{}, nil
- case "KeyValuePairs":
- return []interface{}{}, nil
- case "MostRecentSet":
- return []interface{}{}, nil
- case "KeyPage":
- return []interface{}{}, nil
- case "Size":
- return []interface{}{}, nil
- case "MultiGet":
- return []interface{}{}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubCache) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["AsMap"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 68},
- {Name: "", Type: 66},
- },
- }
- result.Methods["Get"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- {Name: "", Type: 66},
- },
- }
- result.Methods["GetAsBool"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 2},
- {Name: "", Type: 66},
- },
- }
- result.Methods["GetAsByte"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 67},
- {Name: "", Type: 66},
- },
- }
- result.Methods["GetAsError"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 66},
- {Name: "", Type: 66},
- },
- }
- result.Methods["GetAsFloat32"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 25},
- {Name: "", Type: 66},
- },
- }
- result.Methods["GetAsFloat64"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 26},
- {Name: "", Type: 66},
- },
- }
- result.Methods["GetAsInt32"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 36},
- {Name: "", Type: 66},
- },
- }
- result.Methods["GetAsInt64"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 37},
- {Name: "", Type: 66},
- },
- }
- result.Methods["GetAsString"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 3},
- {Name: "", Type: 66},
- },
- }
- result.Methods["GetAsUint32"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 52},
- {Name: "", Type: 66},
- },
- }
- result.Methods["GetAsUint64"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 53},
- {Name: "", Type: 66},
- },
- }
- result.Methods["KeyPage"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "index", Type: 37},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 71},
- {Name: "", Type: 66},
- },
- }
- result.Methods["KeyValuePairs"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 70},
- {Name: "", Type: 66},
- },
- }
- result.Methods["MostRecentSet"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "value", Type: 69},
- {Name: "time", Type: 37},
- {Name: "err", Type: 66},
- },
- }
- result.Methods["MultiGet"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 66},
- },
- InStream: 3,
- OutStream: 65,
- }
- result.Methods["Set"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{
- {Name: "key", Type: 3},
- {Name: "value", Type: 65},
- },
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 66},
- },
- }
- result.Methods["Size"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 37},
- {Name: "", Type: 66},
- },
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "anydata", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.MapType{Key: 0x3, Elem: 0x41, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
- []_gen_wiretype.FieldType{
- _gen_wiretype.FieldType{Type: 0x3, Name: "Key"},
- _gen_wiretype.FieldType{Type: 0x41, Name: "Value"},
- },
- "veyron/examples/wspr_sample.KeyValuePair", []string(nil)},
- _gen_wiretype.SliceType{Elem: 0x45, Name: "", Tags: []string(nil)}, _gen_wiretype.ArrayType{Elem: 0x3, Len: 0xa, Name: "", Tags: []string(nil)}}
-
- return result, nil
-}
-
-func (__gen_s *ServerStubCache) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubCache) Set(call _gen_ipc.ServerCall, key string, value _gen_vdlutil.Any) (err error) {
- err = __gen_s.service.Set(call, key, value)
- return
-}
-
-func (__gen_s *ServerStubCache) Get(call _gen_ipc.ServerCall, key string) (reply _gen_vdlutil.Any, err error) {
- reply, err = __gen_s.service.Get(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) GetAsByte(call _gen_ipc.ServerCall, key string) (reply byte, err error) {
- reply, err = __gen_s.service.GetAsByte(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) GetAsInt32(call _gen_ipc.ServerCall, key string) (reply int32, err error) {
- reply, err = __gen_s.service.GetAsInt32(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) GetAsInt64(call _gen_ipc.ServerCall, key string) (reply int64, err error) {
- reply, err = __gen_s.service.GetAsInt64(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) GetAsUint32(call _gen_ipc.ServerCall, key string) (reply uint32, err error) {
- reply, err = __gen_s.service.GetAsUint32(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) GetAsUint64(call _gen_ipc.ServerCall, key string) (reply uint64, err error) {
- reply, err = __gen_s.service.GetAsUint64(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) GetAsFloat32(call _gen_ipc.ServerCall, key string) (reply float32, err error) {
- reply, err = __gen_s.service.GetAsFloat32(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) GetAsFloat64(call _gen_ipc.ServerCall, key string) (reply float64, err error) {
- reply, err = __gen_s.service.GetAsFloat64(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) GetAsString(call _gen_ipc.ServerCall, key string) (reply string, err error) {
- reply, err = __gen_s.service.GetAsString(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) GetAsBool(call _gen_ipc.ServerCall, key string) (reply bool, err error) {
- reply, err = __gen_s.service.GetAsBool(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) GetAsError(call _gen_ipc.ServerCall, key string) (reply error, err error) {
- reply, err = __gen_s.service.GetAsError(call, key)
- return
-}
-
-func (__gen_s *ServerStubCache) AsMap(call _gen_ipc.ServerCall) (reply map[string]_gen_vdlutil.Any, err error) {
- reply, err = __gen_s.service.AsMap(call)
- return
-}
-
-func (__gen_s *ServerStubCache) KeyValuePairs(call _gen_ipc.ServerCall) (reply []KeyValuePair, err error) {
- reply, err = __gen_s.service.KeyValuePairs(call)
- return
-}
-
-func (__gen_s *ServerStubCache) MostRecentSet(call _gen_ipc.ServerCall) (value KeyValuePair, time int64, err error) {
- value, time, err = __gen_s.service.MostRecentSet(call)
- return
-}
-
-func (__gen_s *ServerStubCache) KeyPage(call _gen_ipc.ServerCall, index int64) (reply [10]string, err error) {
- reply, err = __gen_s.service.KeyPage(call, index)
- return
-}
-
-func (__gen_s *ServerStubCache) Size(call _gen_ipc.ServerCall) (reply int64, err error) {
- reply, err = __gen_s.service.Size(call)
- return
-}
-
-func (__gen_s *ServerStubCache) MultiGet(call _gen_ipc.ServerCall) (err error) {
- stream := &implCacheServiceMultiGetStream{reader: implCacheServiceMultiGetStreamIterator{serverCall: call}, writer: implCacheServiceMultiGetStreamSender{serverCall: call}}
- err = __gen_s.service.MultiGet(call, stream)
- return
-}
diff --git a/examples/wspr_sample/error_thrower.vdl b/examples/wspr_sample/error_thrower.vdl
deleted file mode 100644
index baee28f..0000000
--- a/examples/wspr_sample/error_thrower.vdl
+++ /dev/null
@@ -1,34 +0,0 @@
-package sample
-
-// A testing interface with methods that throw various types of errors
-type ErrorThrower interface {
- // Throws veyron2/vError.Aborted error
- ThrowAborted() error
-
- // Throws veyron2/vError.BadArg error
- ThrowBadArg() error
-
- // Throws veyron2/vError.BadProtocol error
- ThrowBadProtocol() error
-
- // Throws veyron2/vError.Internal error
- ThrowInternal() error
-
- // Throws veyron2/vError.NotAuthorized error
- ThrowNotAuthorized() error
-
- // Throws veyron2/vError.NotFound error
- ThrowNotFound() error
-
- // Throws veyron2/vError.Unknown error
- ThrowUnknown() error
-
- // Throws normal Go error
- ThrowGoError() error
-
- // Throws custom error created by using Standard
- ThrowCustomStandardError() error
-
- // Lists all errors Ids available in veyron2/verror
- ListAllBuiltInErrorIDs() ([]string, error)
-}
\ No newline at end of file
diff --git a/examples/wspr_sample/error_thrower.vdl.go b/examples/wspr_sample/error_thrower.vdl.go
deleted file mode 100644
index 9154975..0000000
--- a/examples/wspr_sample/error_thrower.vdl.go
+++ /dev/null
@@ -1,439 +0,0 @@
-// This file was auto-generated by the veyron vdl tool.
-// Source: error_thrower.vdl
-
-package sample
-
-import (
- // The non-user imports are prefixed with "_gen_" to prevent collisions.
- _gen_veyron2 "veyron2"
- _gen_context "veyron2/context"
- _gen_ipc "veyron2/ipc"
- _gen_naming "veyron2/naming"
- _gen_vdlutil "veyron2/vdl/vdlutil"
- _gen_wiretype "veyron2/wiretype"
-)
-
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
-const _ = _gen_wiretype.TypeIDInvalid
-
-// A testing interface with methods that throw various types of errors
-// ErrorThrower is the interface the client binds and uses.
-// ErrorThrower_ExcludingUniversal is the interface without internal framework-added methods
-// to enable embedding without method collisions. Not to be used directly by clients.
-type ErrorThrower_ExcludingUniversal interface {
- // Throws veyron2/vError.Aborted error
- ThrowAborted(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error)
- // Throws veyron2/vError.BadArg error
- ThrowBadArg(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error)
- // Throws veyron2/vError.BadProtocol error
- ThrowBadProtocol(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error)
- // Throws veyron2/vError.Internal error
- ThrowInternal(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error)
- // Throws veyron2/vError.NotAuthorized error
- ThrowNotAuthorized(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error)
- // Throws veyron2/vError.NotFound error
- ThrowNotFound(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error)
- // Throws veyron2/vError.Unknown error
- ThrowUnknown(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error)
- // Throws normal Go error
- ThrowGoError(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error)
- // Throws custom error created by using Standard
- ThrowCustomStandardError(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error)
- // Lists all errors Ids available in veyron2/verror
- ListAllBuiltInErrorIDs(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error)
-}
-type ErrorThrower interface {
- _gen_ipc.UniversalServiceMethods
- ErrorThrower_ExcludingUniversal
-}
-
-// ErrorThrowerService is the interface the server implements.
-type ErrorThrowerService interface {
-
- // Throws veyron2/vError.Aborted error
- ThrowAborted(context _gen_ipc.ServerContext) (err error)
- // Throws veyron2/vError.BadArg error
- ThrowBadArg(context _gen_ipc.ServerContext) (err error)
- // Throws veyron2/vError.BadProtocol error
- ThrowBadProtocol(context _gen_ipc.ServerContext) (err error)
- // Throws veyron2/vError.Internal error
- ThrowInternal(context _gen_ipc.ServerContext) (err error)
- // Throws veyron2/vError.NotAuthorized error
- ThrowNotAuthorized(context _gen_ipc.ServerContext) (err error)
- // Throws veyron2/vError.NotFound error
- ThrowNotFound(context _gen_ipc.ServerContext) (err error)
- // Throws veyron2/vError.Unknown error
- ThrowUnknown(context _gen_ipc.ServerContext) (err error)
- // Throws normal Go error
- ThrowGoError(context _gen_ipc.ServerContext) (err error)
- // Throws custom error created by using Standard
- ThrowCustomStandardError(context _gen_ipc.ServerContext) (err error)
- // Lists all errors Ids available in veyron2/verror
- ListAllBuiltInErrorIDs(context _gen_ipc.ServerContext) (reply []string, err error)
-}
-
-// BindErrorThrower returns the client stub implementing the ErrorThrower
-// interface.
-//
-// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
-// global Runtime is used.
-func BindErrorThrower(name string, opts ..._gen_ipc.BindOpt) (ErrorThrower, error) {
- var client _gen_ipc.Client
- switch len(opts) {
- case 0:
- // Do nothing.
- case 1:
- if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
- client = clientOpt
- } else {
- return nil, _gen_vdlutil.ErrUnrecognizedOption
- }
- default:
- return nil, _gen_vdlutil.ErrTooManyOptionsToBind
- }
- stub := &clientStubErrorThrower{defaultClient: client, name: name}
-
- return stub, nil
-}
-
-// NewServerErrorThrower creates a new server stub.
-//
-// It takes a regular server implementing the ErrorThrowerService
-// interface, and returns a new server stub.
-func NewServerErrorThrower(server ErrorThrowerService) interface{} {
- return &ServerStubErrorThrower{
- service: server,
- }
-}
-
-// clientStubErrorThrower implements ErrorThrower.
-type clientStubErrorThrower struct {
- defaultClient _gen_ipc.Client
- name string
-}
-
-func (__gen_c *clientStubErrorThrower) client(ctx _gen_context.T) _gen_ipc.Client {
- if __gen_c.defaultClient != nil {
- return __gen_c.defaultClient
- }
- return _gen_veyron2.RuntimeFromContext(ctx).Client()
-}
-
-func (__gen_c *clientStubErrorThrower) ThrowAborted(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "ThrowAborted", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) ThrowBadArg(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "ThrowBadArg", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) ThrowBadProtocol(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "ThrowBadProtocol", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) ThrowInternal(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "ThrowInternal", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) ThrowNotAuthorized(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "ThrowNotAuthorized", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) ThrowNotFound(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "ThrowNotFound", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) ThrowUnknown(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "ThrowUnknown", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) ThrowGoError(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "ThrowGoError", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) ThrowCustomStandardError(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "ThrowCustomStandardError", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) ListAllBuiltInErrorIDs(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "ListAllBuiltInErrorIDs", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-func (__gen_c *clientStubErrorThrower) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
- var call _gen_ipc.Call
- if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
- return
- }
- if ierr := call.Finish(&reply, &err); ierr != nil {
- err = ierr
- }
- return
-}
-
-// ServerStubErrorThrower wraps a server that implements
-// ErrorThrowerService and provides an object that satisfies
-// the requirements of veyron2/ipc.ReflectInvoker.
-type ServerStubErrorThrower struct {
- service ErrorThrowerService
-}
-
-func (__gen_s *ServerStubErrorThrower) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
- // TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
- // Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
- // This will change when it is replaced with Signature().
- switch method {
- case "ThrowAborted":
- return []interface{}{}, nil
- case "ThrowBadArg":
- return []interface{}{}, nil
- case "ThrowBadProtocol":
- return []interface{}{}, nil
- case "ThrowInternal":
- return []interface{}{}, nil
- case "ThrowNotAuthorized":
- return []interface{}{}, nil
- case "ThrowNotFound":
- return []interface{}{}, nil
- case "ThrowUnknown":
- return []interface{}{}, nil
- case "ThrowGoError":
- return []interface{}{}, nil
- case "ThrowCustomStandardError":
- return []interface{}{}, nil
- case "ListAllBuiltInErrorIDs":
- return []interface{}{}, nil
- default:
- return nil, nil
- }
-}
-
-func (__gen_s *ServerStubErrorThrower) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
- result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
- result.Methods["ListAllBuiltInErrorIDs"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 61},
- {Name: "", Type: 65},
- },
- }
- result.Methods["ThrowAborted"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["ThrowBadArg"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["ThrowBadProtocol"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["ThrowCustomStandardError"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["ThrowGoError"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["ThrowInternal"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["ThrowNotAuthorized"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["ThrowNotFound"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
- result.Methods["ThrowUnknown"] = _gen_ipc.MethodSignature{
- InArgs: []_gen_ipc.MethodArgument{},
- OutArgs: []_gen_ipc.MethodArgument{
- {Name: "", Type: 65},
- },
- }
-
- result.TypeDefs = []_gen_vdlutil.Any{
- _gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
-
- return result, nil
-}
-
-func (__gen_s *ServerStubErrorThrower) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
- if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
- return unresolver.UnresolveStep(call)
- }
- if call.Server() == nil {
- return
- }
- var published []string
- if published, err = call.Server().Published(); err != nil || published == nil {
- return
- }
- reply = make([]string, len(published))
- for i, p := range published {
- reply[i] = _gen_naming.Join(p, call.Name())
- }
- return
-}
-
-func (__gen_s *ServerStubErrorThrower) ThrowAborted(call _gen_ipc.ServerCall) (err error) {
- err = __gen_s.service.ThrowAborted(call)
- return
-}
-
-func (__gen_s *ServerStubErrorThrower) ThrowBadArg(call _gen_ipc.ServerCall) (err error) {
- err = __gen_s.service.ThrowBadArg(call)
- return
-}
-
-func (__gen_s *ServerStubErrorThrower) ThrowBadProtocol(call _gen_ipc.ServerCall) (err error) {
- err = __gen_s.service.ThrowBadProtocol(call)
- return
-}
-
-func (__gen_s *ServerStubErrorThrower) ThrowInternal(call _gen_ipc.ServerCall) (err error) {
- err = __gen_s.service.ThrowInternal(call)
- return
-}
-
-func (__gen_s *ServerStubErrorThrower) ThrowNotAuthorized(call _gen_ipc.ServerCall) (err error) {
- err = __gen_s.service.ThrowNotAuthorized(call)
- return
-}
-
-func (__gen_s *ServerStubErrorThrower) ThrowNotFound(call _gen_ipc.ServerCall) (err error) {
- err = __gen_s.service.ThrowNotFound(call)
- return
-}
-
-func (__gen_s *ServerStubErrorThrower) ThrowUnknown(call _gen_ipc.ServerCall) (err error) {
- err = __gen_s.service.ThrowUnknown(call)
- return
-}
-
-func (__gen_s *ServerStubErrorThrower) ThrowGoError(call _gen_ipc.ServerCall) (err error) {
- err = __gen_s.service.ThrowGoError(call)
- return
-}
-
-func (__gen_s *ServerStubErrorThrower) ThrowCustomStandardError(call _gen_ipc.ServerCall) (err error) {
- err = __gen_s.service.ThrowCustomStandardError(call)
- return
-}
-
-func (__gen_s *ServerStubErrorThrower) ListAllBuiltInErrorIDs(call _gen_ipc.ServerCall) (reply []string, err error) {
- reply, err = __gen_s.service.ListAllBuiltInErrorIDs(call)
- return
-}
diff --git a/examples/wspr_sample/sampled/lib/cache_impl.go b/examples/wspr_sample/sampled/lib/cache_impl.go
deleted file mode 100644
index 41df38d..0000000
--- a/examples/wspr_sample/sampled/lib/cache_impl.go
+++ /dev/null
@@ -1,196 +0,0 @@
-package lib
-
-import (
- "fmt"
- "reflect"
- "sort"
- "time"
-
- "veyron2/ipc"
- "veyron2/vdl/vdlutil"
- "veyron2/verror"
-
- sample "veyron/examples/wspr_sample"
-)
-
-var typedNil []int
-
-// A simple in-memory implementation of a Cache service.
-type cacheImpl struct {
- cache map[string]vdlutil.Any
- mostRecent sample.KeyValuePair
- lastUpdateTime time.Time
-}
-
-// NewCached returns a new implementation of the CacheService.
-func NewCached() sample.CacheService {
- return &cacheImpl{cache: make(map[string]vdlutil.Any)}
-}
-
-// Set sets a value for a key. This should never return an error.
-func (c *cacheImpl) Set(_ ipc.ServerContext, key string, value vdlutil.Any) error {
- c.cache[key] = value
- c.mostRecent = sample.KeyValuePair{Key: key, Value: value}
- c.lastUpdateTime = time.Now()
- return nil
-}
-
-// Get returns the value for a key. If the key is not in the map, it returns
-// an error.
-func (c *cacheImpl) Get(_ ipc.ServerContext, key string) (vdlutil.Any, error) {
- if value, ok := c.cache[key]; ok {
- return value, nil
- }
-
- return typedNil, verror.NotFoundf("key not found: %v", key)
-}
-
-// getWithTypeCheck gets the key and tests if its type matches the given time, erroring if it does
-// not.
-// This exists mostly to shorted the Get* methods below.
-func (c *cacheImpl) getWithTypeCheck(key string, rt reflect.Type) (interface{}, error) {
- v, err := c.Get(nil, key)
- if err != nil {
- return reflect.Zero(rt).Interface(), err
- }
- if !reflect.TypeOf(v).AssignableTo(rt) {
- return reflect.Zero(rt).Interface(),
- fmt.Errorf("Cannot convert %v (type %v) to type %v", v, reflect.TypeOf(v), rt)
- }
- return v, nil
-}
-
-// Same as Get, but casts the return argument to an int32.
-func (c *cacheImpl) GetAsInt32(_ ipc.ServerContext, key string) (int32, error) {
- v, err := c.getWithTypeCheck(key, reflect.TypeOf(int32(0)))
- return v.(int32), err
-}
-
-// Same as Get, but casts the return argument to an int64.
-func (c *cacheImpl) GetAsInt64(_ ipc.ServerContext, key string) (int64, error) {
- v, err := c.getWithTypeCheck(key, reflect.TypeOf(int64(0)))
- return v.(int64), err
-}
-
-// Same as Get, but casts the return argument to an uint8.
-func (c *cacheImpl) GetAsByte(_ ipc.ServerContext, key string) (byte, error) {
- v, err := c.getWithTypeCheck(key, reflect.TypeOf(byte(0)))
- return v.(uint8), err
-}
-
-// Same as Get, but casts the return argument to an uint32.
-func (c *cacheImpl) GetAsUint32(_ ipc.ServerContext, key string) (uint32, error) {
- v, err := c.getWithTypeCheck(key, reflect.TypeOf(uint32(0)))
- return v.(uint32), err
-}
-
-// Same as Get, but casts the return argument to an uint64.
-func (c *cacheImpl) GetAsUint64(_ ipc.ServerContext, key string) (uint64, error) {
- v, err := c.getWithTypeCheck(key, reflect.TypeOf(uint64(0)))
- return v.(uint64), err
-}
-
-// Same as Get, but casts the return argument to a float32.
-func (c *cacheImpl) GetAsFloat32(_ ipc.ServerContext, key string) (float32, error) {
- v, err := c.getWithTypeCheck(key, reflect.TypeOf(float32(0)))
- return v.(float32), err
-}
-
-// Same as Get, but casts the return argument to a float64.
-func (c *cacheImpl) GetAsFloat64(_ ipc.ServerContext, key string) (float64, error) {
- v, err := c.getWithTypeCheck(key, reflect.TypeOf(float64(0)))
- return v.(float64), err
-}
-
-// Same as Get, but casts the return argument to a string.
-func (c *cacheImpl) GetAsString(_ ipc.ServerContext, key string) (string, error) {
- v, err := c.getWithTypeCheck(key, reflect.TypeOf(""))
- return v.(string), err
-}
-
-// Same as Get, but casts the return argument to a bool.
-func (c *cacheImpl) GetAsBool(_ ipc.ServerContext, key string) (bool, error) {
- v, err := c.getWithTypeCheck(key, reflect.TypeOf(false))
- return v.(bool), err
-}
-
-// Same as Get, but converts the string return argument to an error.
-func (c *cacheImpl) GetAsError(_ ipc.ServerContext, key string) (storedError error, callError error) {
- v, err := c.getWithTypeCheck(key, reflect.TypeOf([]error{}).Elem())
- return v.(error), err
-}
-
-// AsMap returns the full contents of the cache as a map.
-func (c *cacheImpl) AsMap(ipc.ServerContext) (map[string]vdlutil.Any, error) {
- return c.cache, nil
-}
-
-// KeyValuePairs returns the full contents of the cache as a slice of pairs.
-func (c *cacheImpl) KeyValuePairs(ipc.ServerContext) ([]sample.KeyValuePair, error) {
- kvp := make([]sample.KeyValuePair, 0, len(c.cache))
- for key, val := range c.cache {
- kvp = append(kvp, sample.KeyValuePair{key, val})
- }
- return kvp, nil
-}
-
-// MostRecentSet returns the key and value and the timestamp for the most
-// recent set operation
-// TODO(bprosnitz) support type types and change time to native time type
-func (c *cacheImpl) MostRecentSet(ipc.ServerContext) (sample.KeyValuePair, int64, error) {
- var err error
- if c.lastUpdateTime.IsZero() {
- err = verror.NotFoundf("no values in the cache so cannot return most recent.")
- }
- return c.mostRecent, c.lastUpdateTime.Unix(), err
-}
-
-// KeyPage indexes into the keys (in alphanumerically sorted order) and
-// returns the indexth page of 10 keys.
-func (c *cacheImpl) KeyPage(_ ipc.ServerContext, index int64) ([10]string, error) {
- results := [10]string{}
-
- keys := sort.StringSlice{}
- for key, _ := range c.cache {
- keys = append(keys, key)
- }
- keys.Sort()
-
- lowIndex := int(index) * 10
- if index < 0 || len(keys) <= lowIndex {
- return results, verror.BadArgf("Page index out of bounds: %d", index)
- }
- highIndex := lowIndex + 9
- if highIndex > len(keys)-1 {
- highIndex = len(keys) - 1
- }
-
- for i := 0; lowIndex+i <= highIndex; i++ {
- results[i] = keys[lowIndex+i]
- }
-
- return results, nil
-}
-
-// Size returns the total number of entries in the cache.
-func (c *cacheImpl) Size(ipc.ServerContext) (int64, error) {
- return int64(len(c.cache)), nil
-}
-
-// MultiGet handles a stream of get requests. Returns an error if one of the
-// keys in the stream is not in the map or if there was an issue reading
-// the stream.
-func (c *cacheImpl) MultiGet(_ ipc.ServerContext, stream sample.CacheServiceMultiGetStream) error {
- rStream := stream.RecvStream()
- sender := stream.SendStream()
- for rStream.Advance() {
- key := rStream.Value()
-
- value, ok := c.cache[key]
- if !ok {
- return fmt.Errorf("key not found: %v", key)
- }
- sender.Send(value)
- }
- return rStream.Err()
-}
diff --git a/examples/wspr_sample/sampled/lib/error_thrower_impl.go b/examples/wspr_sample/sampled/lib/error_thrower_impl.go
deleted file mode 100644
index e352b62..0000000
--- a/examples/wspr_sample/sampled/lib/error_thrower_impl.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package lib
-
-import (
- "errors"
-
- "veyron2/ipc"
- "veyron2/verror"
-
- sample "veyron/examples/wspr_sample"
-)
-
-// NewCached returns a new implementation of the ErrorThrowerService.
-func NewErrorThrower() sample.ErrorThrowerService {
- return &errorThrowerImpl{}
-}
-
-type errorThrowerImpl struct{}
-
-func (e *errorThrowerImpl) ThrowAborted(_ ipc.ServerContext) error {
- return verror.Abortedf("Aborted!")
-}
-
-func (e *errorThrowerImpl) ThrowBadArg(_ ipc.ServerContext) error {
- return verror.BadArgf("BadArg!")
-}
-
-func (e *errorThrowerImpl) ThrowBadProtocol(_ ipc.ServerContext) error {
- return verror.BadProtocolf("BadProtocol!")
-}
-
-func (e *errorThrowerImpl) ThrowInternal(_ ipc.ServerContext) error {
- return verror.Internalf("Internal!")
-}
-
-func (e *errorThrowerImpl) ThrowNotAuthorized(_ ipc.ServerContext) error {
- return verror.NotAuthorizedf("NotAuthorized!")
-}
-
-func (e *errorThrowerImpl) ThrowNotFound(_ ipc.ServerContext) error {
- return verror.NotFoundf("NotFound!")
-}
-
-func (e *errorThrowerImpl) ThrowUnknown(_ ipc.ServerContext) error {
- return verror.Unknownf("Unknown!")
-}
-
-func (e *errorThrowerImpl) ThrowGoError(_ ipc.ServerContext) error {
- return errors.New("GoError!")
-}
-
-func (e *errorThrowerImpl) ThrowCustomStandardError(_ ipc.ServerContext) error {
- return verror.Standard{
- ID: "MyCustomError",
- Msg: "CustomStandard!",
- }
-}
-
-func (e *errorThrowerImpl) ListAllBuiltInErrorIDs(_ ipc.ServerContext) ([]string, error) {
- // TODO(aghassemi) Use when we have enum for error IDs in IDL
- // This is not used yet but the idea is to pass all error types in veyron2/verror to
- // JavaScript so if a new one is added, this test would break and we add the new one to
- // JavaScript as well. There is no way to enumerate all error IDs right now since they
- // are constants and not an Enum. Enum support is coming later.
- return nil, nil
-}
diff --git a/examples/wspr_sample/sampled/lib/sampled.go b/examples/wspr_sample/sampled/lib/sampled.go
deleted file mode 100644
index aca80b5..0000000
--- a/examples/wspr_sample/sampled/lib/sampled.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package lib
-
-import (
- "fmt"
- "strings"
-
- "veyron2"
- "veyron2/ipc"
- "veyron2/naming"
- "veyron2/security"
-
- sample "veyron/examples/wspr_sample"
-)
-
-type cacheDispatcher struct {
- cache interface{}
- errorThrower interface{}
-}
-
-func (cd *cacheDispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
- if strings.HasPrefix(suffix, "errorThrower") {
- return ipc.ReflectInvoker(cd.errorThrower), nil, nil
- }
- return ipc.ReflectInvoker(cd.cache), nil, nil
-}
-
-func StartServer(r veyron2.Runtime) (ipc.Server, naming.Endpoint, error) {
- // Create a new server instance.
- s, err := r.NewServer()
- if err != nil {
- return nil, nil, fmt.Errorf("failure creating server: %v", err)
- }
-
- disp := &cacheDispatcher{
- cache: sample.NewServerCache(NewCached()),
- errorThrower: sample.NewServerErrorThrower(NewErrorThrower()),
- }
-
- // Create an endpoint and begin listening.
- endpoint, err := s.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- return nil, nil, fmt.Errorf("error listening to service: %v", err)
- }
-
- // Publish the cache service. This will register it in the mount table and
- // maintain the registration until StopServing is called.
- if err := s.Serve("cache", disp); err != nil {
- return nil, nil, fmt.Errorf("error publishing service: %v", err)
- }
- return s, endpoint, nil
-}
diff --git a/examples/wspr_sample/sampled/lib/sampled_test.go b/examples/wspr_sample/sampled/lib/sampled_test.go
deleted file mode 100644
index ab531ff..0000000
--- a/examples/wspr_sample/sampled/lib/sampled_test.go
+++ /dev/null
@@ -1,320 +0,0 @@
-package lib
-
-import (
- "errors"
- "reflect"
- "testing"
- "time"
-
- "veyron2/context"
- "veyron2/ipc"
- "veyron2/naming"
- "veyron2/rt"
- "veyron2/vdl/vdlutil"
- "veyron2/verror"
-
- hps "veyron/examples/wspr_sample"
-)
-
-// getCacheClient initializes the runtime and creates a client binding.
-func getCacheClient(address string) (hps.Cache, error) {
- rt.Init()
-
- // Bind to a rooted, terminal name to bypass the MountTable which isn't
- // actually used, nor needed, in these tests.
- s, err := hps.BindCache(naming.JoinAddressName(address, "//cache"))
- if err != nil {
- return nil, err
- }
-
- return s, nil
-}
-
-// TestValueSetGet tests setting values and then calling various Get* functions.
-func TestValueSetGet(t *testing.T) {
- type testCase struct {
- mapFieldName string
- nameOfGetMethod string
- v interface{}
- shouldGetError bool
- }
- tests := []testCase{
- testCase{"val", "Get", "Test", false},
- testCase{"val", "Get", 4, false},
- testCase{"val", "Get", struct {
- X int
- Y string
- }{4, "Test"}, false},
- testCase{"i32", "GetAsInt32", int32(1), false},
- testCase{"i64", "GetAsInt64", int64(1), false},
- testCase{"byt", "GetAsByte", byte(1), false},
- testCase{"ui32", "GetAsUint32", uint32(1), false},
- testCase{"ui64", "GetAsUint64", uint64(1), false},
- testCase{"fl32", "GetAsFloat32", float32(1), false},
- testCase{"fl64", "GetAsFloat64", float64(1), false},
- testCase{"b", "GetAsBool", true, false},
- testCase{"s", "GetAsString", "Test", false},
- testCase{"err", "GetAsError", verror.ToStandard(errors.New("Test Error")), false},
- testCase{"err_i8", "GetAsByte", int64(4), true},
- testCase{"err_i64", "GetAsInt64", int8(1), true},
- testCase{"err_string", "GetAsString", true, true},
- }
- r := rt.Init()
- ctx := r.NewContext()
-
- s, endpoint, err := StartServer(r)
- if err != nil {
- t.Fatal("failed to start server: ", err)
- }
- defer s.Stop()
- c, err := getCacheClient(endpoint.String())
- if err != nil {
- t.Fatal("failed to connect client: ", err)
- }
- for _, test := range tests {
- // Call Set().
- if err := c.Set(ctx, test.mapFieldName, test.v); err != nil {
- t.Errorf("error setting: %v (test case: %v)", err, test)
- continue
- }
-
- meth := reflect.ValueOf(c).MethodByName(test.nameOfGetMethod)
- out := meth.Call([]reflect.Value{reflect.ValueOf(ctx), reflect.ValueOf(test.mapFieldName)})
- if !test.shouldGetError {
- if out[1].Interface() != nil {
- t.Errorf("error getting: %v (test case: %v)", err, test)
- continue
- }
- if out[0].Interface() != test.v {
- t.Errorf("returned result does not match")
- }
- } else if out[1].Interface() == nil {
- t.Errorf("expected error in case %v", test)
- }
-
- }
-}
-
-// settable mirrors the cache's Set method to provide a consistent way to populate test cases.
-type settable interface {
- Set(ctx context.T, key string, val vdlutil.Any, opts ...ipc.CallOpt) error
-}
-
-// populateObject populates a settable with 12 values.
-func populateObject(ctx context.T, s settable) error {
- if err := s.Set(ctx, "A", int8(3)); err != nil {
- return err
- }
- // Set "A" again to ensure it takes the second value.
- if err := s.Set(ctx, "A", "A"); err != nil {
- return err
- }
- if err := s.Set(ctx, "B", uint16(5)); err != nil {
- return err
- }
- if err := s.Set(ctx, "C", uint32(7)); err != nil {
- return err
- }
- if err := s.Set(ctx, "D", verror.ToStandard(errors.New("Err"))); err != nil {
- return err
- }
- if err := s.Set(ctx, "E", true); err != nil {
- return err
- }
- if err := s.Set(ctx, "F", float32(5.4)); err != nil {
- return err
- }
- if err := s.Set(ctx, "G", struct {
- X int
- Y string
- }{4, "G"}); err != nil {
- return err
- }
- if err := s.Set(ctx, "H", uint64(8)); err != nil {
- return err
- }
- if err := s.Set(ctx, "I", "I"); err != nil {
- return err
- }
- if err := s.Set(ctx, "J", float64(8.3)); err != nil {
- return err
- }
- if err := s.Set(ctx, "K", int64(2)); err != nil {
- return err
- }
- if err := s.Set(ctx, "L", int8(9)); err != nil {
- return err
- }
- return nil
-}
-
-// setupManyResults starts a server and client and populates the server with the values in populateObject.
-func setupManyResults(t *testing.T) (hps.Cache, ipc.Server) {
- r := rt.Init()
- s, endpoint, err := StartServer(r)
- if err != nil {
- t.Fatal("failed to start server: ", err)
- }
- c, err := getCacheClient(endpoint.String())
- if err != nil {
- t.Fatal("failed to connect client: ", err)
- }
-
- if err := populateObject(r.NewContext(), c.(settable)); err != nil {
- t.Fatal("error populating cache: ", err)
- }
-
- return c, s
-}
-
-// settableMap is a map that implements the settable interface.
-type settableMap map[string]vdlutil.Any
-
-func (sm settableMap) Set(ctx context.T, key string, val vdlutil.Any, opts ...ipc.CallOpt) error {
- sm[key] = val
- return nil
-}
-
-// TestAsMap tests that AsMap returns the correct results.
-func TestAsMap(t *testing.T) {
- c, s := setupManyResults(t)
- defer s.Stop()
-
- ctx := rt.R().NewContext()
-
- res, err := c.AsMap(ctx)
- if err != nil {
- t.Fatal("error calling AsMap: ", err)
- }
-
- m := settableMap(make(map[string]vdlutil.Any))
- if err := populateObject(ctx, m); err != nil {
- t.Fatal("error populating map: ", err)
- }
-
- for key, val := range m {
- otherVal := res[key]
- if val != otherVal {
- t.Errorf("didn't match: %v and %v", val, otherVal)
- }
- }
-}
-
-// TestKeyValuePairs tests that KeyValuePairs returns the correct results.
-func TestKeyValuePairs(t *testing.T) {
- c, s := setupManyResults(t)
- defer s.Stop()
-
- ctx := rt.R().NewContext()
- res, err := c.KeyValuePairs(ctx)
- if err != nil {
- t.Fatal("error calling KeyValuePairs: ", err)
- }
-
- m := settableMap(make(map[string]vdlutil.Any))
- if err := populateObject(ctx, m); err != nil {
- t.Fatal("error populating map: ", err)
- }
-
- for _, kvp := range res {
- otherVal := m[kvp.Key]
- if kvp.Value != otherVal {
- t.Errorf("didn't match: %v and %v", kvp.Value, otherVal)
- }
- }
-}
-
-// TestKeyPageAndSize tests the KeyPage and size methods.
-func TestKeyPageAndSize(t *testing.T) {
- c, s := setupManyResults(t)
- defer s.Stop()
-
- ctx := rt.R().NewContext()
- sz, err := c.Size(ctx)
- if err != nil {
- t.Fatal("error calling Size: ", err)
- }
- if sz != 12 {
- t.Fatal("wrong number of results: ", sz)
- }
-
- res, err := c.KeyPage(ctx, 1)
- if err != nil {
- t.Fatal("error calling AsMap: ", err)
- }
-
- if res[0] != "K" || res[1] != "L" || res[2] != "" {
- t.Fatalf("incorrect page results: %v", res)
- }
-}
-
-// TestMostRecentSet tests the MostRecentSet method.
-func TestMostRecentSet(t *testing.T) {
- c, s := setupManyResults(t)
- defer s.Stop()
-
- ctx := rt.R().NewContext()
-
- timeBefore := time.Now().Unix()
- if err := c.Set(ctx, "B", int32(8)); err != nil {
- t.Fatal("error calling Set: ", err)
- }
- timeAfter := time.Now().Unix()
-
- kvp, setTime, err := c.MostRecentSet(ctx)
- if err != nil {
- t.Fatal("error calling MostRecentSet: ", err)
- }
-
- if kvp.Key != "B" || kvp.Value != int32(8) {
- t.Errorf("unexpected key value pair: %v", kvp)
- }
-
- if setTime < timeBefore || setTime > timeAfter {
- t.Errorf("time %v out of range [%v, %v]", setTime, timeBefore, timeAfter)
- }
-}
-
-// TestMultiGet tests the MultiGet method.
-func TestMultiGet(t *testing.T) {
- c, s := setupManyResults(t)
- defer s.Stop()
-
- stream, err := c.MultiGet(rt.R().NewContext())
- if err != nil {
- t.Fatal("error calling MultiGet: ", err)
- }
-
- sender := stream.SendStream()
-
- sender.Send("A")
- sender.Send("C")
- sender.Send("E")
-
- rStream := stream.RecvStream()
- if rStream.Advance() {
- if rStream.Value() != "A" {
- t.Errorf("value for 'A' didn't match")
- }
- } else {
- t.Fatal("error on advance: %v", rStream.Err())
- }
-
- if rStream.Advance() {
- if rStream.Value() != uint32(7) {
- t.Errorf("value for 'C' didn't match")
- }
- } else {
- t.Fatal("error on advance: %v", rStream.Err())
- }
-
- if rStream.Advance() {
- if rStream.Value() != true {
- t.Errorf("value for 'E' didn't match")
- }
- } else {
- t.Fatal("error on advance: %v", rStream.Err())
- }
-
- sender.Close()
-}
diff --git a/examples/wspr_sample/sampled/main.go b/examples/wspr_sample/sampled/main.go
deleted file mode 100644
index 0860680..0000000
--- a/examples/wspr_sample/sampled/main.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package main
-
-import (
- "fmt"
- "log"
-
- "veyron/examples/wspr_sample/sampled/lib"
- "veyron/lib/signals"
- "veyron2/rt"
-)
-
-func main() {
- // Create the runtime
- r := rt.Init()
- defer r.Cleanup()
-
- s, endpoint, err := lib.StartServer(r)
- if err != nil {
- log.Fatal("", err)
- }
- defer s.Stop()
-
- fmt.Printf("Listening at: %v\n", endpoint)
- <-signals.ShutdownOnSignals()
-}