hunk.code_window: var conn = null;
   var connectFailCount = 0;
   var pastFirstInit = false;
   export function initialize() {
       if (window.WebSocket && !conn) {
           let protocol = 'ws://';
  
hunk.labels: keep keep add keep keep keep keep
hunk.after_edit: var manuallyClosed = false;
  
hunk.file_path: webapp/action_creators/websocket_actions.jsx
hunk.type: add
file: // Package translation defines the interface for a translation.
  package translation
  
  import (
  	"fmt"
  
  	"github.com/nicksnyder/go-i18n/i18n/language"
  )
  
  // Translation is the interface that represents a translated string.
  type Translation interface {
  	// MarshalInterface returns the object that should be used
  	// to serialize the translation.
  	MarshalInterface() interface{}
  	ID() string
  	Template(language.Plural) *template
  	UntranslatedCopy() Translation
  	Normalize(language *language.Language) Translation
  	Backfill(src Translation) Translation
  	Merge(Translation) Translation
  	Incomplete(l *language.Language) bool
  }
  
  // SortableByID implements sort.Interface for a slice of translations.
  type SortableByID []Translation
  
  func (a SortableByID) Len() int           { return len(a) }
  func (a SortableByID) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
  func (a SortableByID) Less(i, j int) bool { return a[i].ID() < a[j].ID() }
  
  // NewTranslation reflects on data to create a new Translation.
  //
  // data["id"] must be a string and data["translation"] must be either a string
  // for a non-plural translation or a map[string]interface{} for a plural translation.
  func NewTranslation(data map[string]interface{}) (Translation, error) {
  	id, ok := data["id"].(string)
  	if !ok {
  		return nil, fmt.Errorf(`missing "id" key`)
  	}
  	var pluralObject map[string]interface{}
  	switch translation := data["translation"].(type) {
  	case string:
  		tmpl, err := newTemplate(translation)
  		if err != nil {
  			return nil, err
  		}
  		return &singleTranslation{id, tmpl}, nil
  	case map[interface{}]interface{}:
  		// The YAML parser uses interface{} keys so we first convert them to string keys.
  		pluralObject = make(map[string]interface{})
  		for k, v := range translation {
  			kStr, ok := k.(string)
  			if !ok {
  				return nil, fmt.Errorf(`invalid plural category type %T; expected string`, k)
  			}
  			pluralObject[kStr] = v
  		}
  	case map[string]interface{}:
  		pluralObject = translation
  	case nil:
  		return nil, fmt.Errorf(`missing "translation" key`)
  	default:
  		return nil, fmt.Errorf(`unsupported type for "translation" key %T`, translation)
  	}
  
  	templates := make(map[language.Plural]*template, len(pluralObject))
  	for k, v := range pluralObject {
  		pc, err := language.NewPlural(k)
  		if err != nil {
  			return nil, err
  		}
  		str, ok := v.(string)
  		if !ok {
  			return nil, fmt.Errorf(`plural category "%s" has value of type %T; expected string`, pc, v)
  		}
  		tmpl, err := newTemplate(str)
  		if err != nil {
  			return nil, err
  		}
  		templates[pc] = tmpl
  	}
  	return &pluralTranslation{id, templates}, nil
  }
  