type Query {
  newsTeasers: [NewsTeaserNode]
  survey(id: ID): SurveyNode
  surveys(offset: Int, before: String, after: String, first: Int, last: Int): SurveyNodeConnection
  project(id: ID, slug: String): ProjectNode
  projects: [ProjectNode]
  instrument(slug: String, id: ID): InstrumentNode
  instruments: [InstrumentNode]
  instrumentTypes: [InstrumentTypeNode]
  instrumentCategories: [InstrumentCategoryNode]
  studentSubmission(id: ID!): StudentSubmissionNode
  assignment(
    """The ID of the object"""
    id: ID!
  ): AssignmentNode
  assignments: [AssignmentNode]
  node(
    """The ID of the object"""
    id: ID!
  ): Node
  topic(slug: String): TopicOr404Node
  module(slug: String, id: ID): ModuleNode
  chapter(
    """The ID of the object"""
    id: ID!
  ): ChapterNode
  contentBlock(
    """The ID of the object"""
    id: ID!
  ): ContentBlockNode
  snapshot(
    """The ID of the object"""
    id: ID!
  ): SnapshotNode
  topics(before: String, after: String, first: Int, last: Int): TopicConnection
  modules(before: String, after: String, first: Int, last: Int): ModuleConnection
  chapters(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ChapterNodeConnection
  moduleLevel(id: ID!): ModuleLevelNode
  moduleLevels: [ModuleLevelNode]
  moduleCategory(id: ID!): ModuleCategoryNode
  moduleCategories: [ModuleCategoryNode]
  objectiveGroup(
    """The ID of the object"""
    id: ID!
  ): ObjectiveGroupNode
  objectiveGroups(offset: Int, before: String, after: String, first: Int, last: Int, title: ObjectivesObjectiveGroupTitleChoices, module_Slug: String): ObjectiveGroupNodeConnection
  roomEntry(id: ID, slug: String): RoomEntryNode
  room(slug: String, id: ID, appearance: String): RoomNode
  rooms: [RoomNode]
  allRoomEntries(offset: Int, before: String, after: String, first: Int, last: Int, slug: String): RoomEntryNodeConnection
  moduleRoom(slug: String, classId: ID): RoomNode
  me: PrivateUserNode
  allUsers(offset: Int, before: String, after: String, first: Int, last: Int, username: String, email: String): PrivateUserNodeConnection
  myActivity(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, slug_Icontains: String, slug_In: [String], title: String, title_Icontains: String, title_In: [String]): ModuleNodeConnection
  myInstrumentActivity(offset: Int, before: String, after: String, first: Int, last: Int, slug: String): InstrumentNodeConnection
  myActivities: ActivityNode
  _debug: DjangoDebug
}

type NewsTeaserNode implements Node {
  """The ID of the object"""
  id: ID!
  imageUrl: String
  title: String!
  description: String
  date: Date
  orderId: Int!
  newsArticleUrl: String
  imageSource: String!
  displayDate: String
}

"""An object with an ID"""
interface Node {
  """The ID of the object"""
  id: ID!
}

"""
The `Date` scalar type represents a Date
value as specified by
[iso8601](https://en.wikipedia.org/wiki/ISO_8601).
"""
scalar Date

type SurveyNode implements Node {
  """The ID of the object"""
  id: ID!
  title: String!
  module: ModuleNode
  data: JSONString!
  answers(offset: Int, before: String, after: String, first: Int, last: Int): AnswerNodeConnection!
  pk: Int
  answer: AnswerNode
  path: String!
}

type ModuleNode implements ModuleInterface {
  """Der Seitentitel, der öffentlich angezeigt werden soll"""
  title: String!

  """
  Der Name der Seite, wie er in URLs angezeigt werden soll, z.B. http://domain.com/blog/[my-slug]/
  """
  slug: String!

  """e.g. 'Intro' or 'Modul 1'"""
  metaTitle: String!
  level: ModuleLevelNode
  category: ModuleCategoryNode
  heroImage: String!

  """e.g. 'Reuters', 'Wikipedia'"""
  heroSource: String!
  teaser: String!
  intro: String!
  assignments: [AssignmentNode]
  objectiveGroups: [ObjectiveGroupNode]

  """The ID of the object"""
  id: ID!
  pk: Int
  topic: TopicNode
  chapters: [ChapterNode]
  solutionsEnabled: Boolean
  bookmark: ModuleBookmarkNode
  mySubmissions: [StudentSubmissionNode]
  myAnswers: [AnswerNode]
  myContentBookmarks(offset: Int, before: String, after: String, first: Int, last: Int): ContentBlockBookmarkNodeConnection
  myChapterBookmarks(offset: Int, before: String, after: String, first: Int, last: Int): ChapterBookmarkNodeConnection
  snapshots: [SnapshotNode]
  language: String
  highlights: [HighlightNode]
  myHighlights: [HighlightNode!]!
  myBookmarks: [BookmarkNode]
  path: String
}

interface ModuleInterface {
  """The ID of the object"""
  id: ID!
  pk: Int
  heroImage: String!
  topic: TopicNode
}

type TopicNode implements Node {
  """Der Seitentitel, der öffentlich angezeigt werden soll"""
  title: String!

  """
  Der Name der Seite, wie er in URLs angezeigt werden soll, z.B. http://domain.com/blog/[my-slug]/
  """
  slug: String!

  """Order of the topic"""
  order: Int!
  teaser: String!
  description: String!
  vimeoId: String
  instructions: String

  """The ID of the object"""
  id: ID!
  pk: Int
  modules: [ModuleNode!]
  highlights: [HighlightNode]
}

type HighlightNode implements Node {
  """The ID of the object"""
  id: ID!
  user: PrivateUserNode!
  page: HighlightableNode!
  contentIndex: Int
  contentUuid: UUID
  paragraphIndex: Int!
  startPosition: Int!
  selectionLength: Int!
  text: String!
  note: NoteNode
  color: String!
}

type PrivateUserNode implements Node {
  firstName: String!
  lastName: String!
  avatarUrl: String!

  """
  Erforderlich. 150 Zeichen oder weniger. Nur Buchstaben, Ziffern und @/./+/-/_.
  """
  username: String!
  lastModule: ModuleNode
  lastModuleLevel: ModuleLevelNode
  lastTopic: TopicNode
  email: String!
  onboardingVisited: Boolean!
  team: TeamNode
  schoolClasses: [SchoolClassNode]

  """The ID of the object"""
  id: ID!
  pk: Int
  permissions: [String]
  selectedClass: SchoolClassNode
  expiryDate: String
  isTeacher: Boolean
  oldClasses: [SchoolClassNode]
  recentModules(
    offset: Int
    before: String
    after: String
    first: Int
    last: Int
    recentModules: ID

    """Sortierung"""
    orderBy: String
  ): ModuleNodeConnection
  readOnly: Boolean
}

type ModuleLevelNode implements Node {
  """The ID of the object"""
  id: ID!
  name: String!
  filterAttributeType: BooksModuleLevelFilterAttributeTypeChoices!

  """Order in the Dropdown List"""
  order: Int!
  moduleSet(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, slug_Icontains: String, slug_In: [String], title: String, title_Icontains: String, title_In: [String]): ModuleNodeConnection!
}

"""An enumeration."""
enum BooksModuleLevelFilterAttributeTypeChoices {
  """All"""
  ALL

  """Exact"""
  EXACT
}

type ModuleNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [ModuleNodeEdge]!
}

"""
The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
"""
type PageInfo {
  """When paginating forwards, are there more items?"""
  hasNextPage: Boolean!

  """When paginating backwards, are there more items?"""
  hasPreviousPage: Boolean!

  """When paginating backwards, the cursor to continue."""
  startCursor: String

  """When paginating forwards, the cursor to continue."""
  endCursor: String
}

"""A Relay edge containing a `ModuleNode` and its cursor."""
type ModuleNodeEdge {
  """The item at the end of the edge"""
  node: ModuleNode

  """A cursor for use in pagination"""
  cursor: String!
}

type TeamNode implements Node {
  """The ID of the object"""
  id: ID!
  name: String!
  isDeleted: Boolean!
  code: String
  creator: PrivateUserNode
  members: [PublicUserNode]
  pk: Int
}

type PublicUserNode implements Node {
  firstName: String!
  lastName: String!
  avatarUrl: String!

  """The ID of the object"""
  id: ID!
  fullName: String!
  isMe: Boolean
}

type SchoolClassNode implements Node {
  name: String!
  code: String

  """The ID of the object"""
  id: ID!
  pk: Int
  members: [ClassMemberNode]
  readOnly: Boolean
}

"""
We need to build this ourselves, because we want the active property on the node, because providing it on the
Connection or Edge for a UserNodeConnection is difficult.
"""
type ClassMemberNode {
  user: PublicUserNode
  active: Boolean
  firstName: String
  lastName: String
  isTeacher: Boolean
  id: ID
  isMe: Boolean
}

union HighlightableNode = ContentBlockNode | InstrumentNode | ModuleNode | ChapterNode

type ContentBlockNode implements Node & ContentBlockInterface {
  title: String

  """
  Der Name der Seite, wie er in URLs angezeigt werden soll, z.B. http://domain.com/blog/[my-slug]/
  """
  slug: String!
  hiddenFor: [SchoolClassNode]
  visibleFor: [SchoolClassNode]
  userCreated: Boolean!
  contents: GenericStreamFieldType
  type: String!

  """The ID of the object"""
  id: ID!
  mine: Boolean
  bookmarks: [ContentBlockBookmarkNode]
  originalCreator: PublicUserNode
  instrumentCategory: InstrumentCategoryNode
  path: String
  highlights: [HighlightNode]
}

interface ContentBlockInterface {
  title: String
  contents: GenericStreamFieldType
  type: String!
}

scalar GenericStreamFieldType

type ContentBlockBookmarkNode implements Node {
  """The ID of the object"""
  id: ID!
  user: PrivateUserNode!
  note: NoteNode
  uuid: UUID
  contentBlock: ContentBlockNode!
  path: String
  content: String
}

type NoteNode implements Node {
  """The ID of the object"""
  id: ID!
  text: String!
  contentblockbookmark: ContentBlockBookmarkNode
  modulebookmark: ModuleBookmarkNode
  chapterbookmark: ChapterBookmarkNode
  instrumentbookmark: InstrumentBookmarkNode
  highlight: HighlightNode
  pk: Int
}

type ModuleBookmarkNode {
  id: ID!
  user: PrivateUserNode!
  note: NoteNode
  module: ModuleNode!
  path: String
  content: String
}

type ChapterBookmarkNode implements Node {
  """The ID of the object"""
  id: ID!
  user: PrivateUserNode!
  note: NoteNode
  chapter: ChapterNode!
  path: String
  content: String
}

type ChapterNode implements Node & ChapterInterface {
  title: String

  """
  Der Name der Seite, wie er in URLs angezeigt werden soll, z.B. http://domain.com/blog/[my-slug]/
  """
  slug: String!
  description: String
  titleHiddenFor: [SchoolClassNode]
  descriptionHiddenFor: [SchoolClassNode]

  """The ID of the object"""
  id: ID!
  bookmark: ChapterBookmarkNode
  contentBlocks: [ContentBlockNode]
  path: String
  highlights: [HighlightNode]
}

interface ChapterInterface {
  description: String
  title: String
}

type InstrumentBookmarkNode implements Node {
  """The ID of the object"""
  id: ID!
  user: PrivateUserNode!
  note: NoteNode
  uuid: UUID
  instrument: InstrumentNode!
  path: String!
  content: String
}

"""
Leverages the internal Python implementation of UUID (uuid.UUID) to provide native UUID objects
in fields, resolvers and input.
"""
scalar UUID

type InstrumentNode implements Node {
  """Der Seitentitel, der öffentlich angezeigt werden soll"""
  title: String!

  """
  Der Name der Seite, wie er in URLs angezeigt werden soll, z.B. http://domain.com/blog/[my-slug]/
  """
  slug: String!
  intro: String!
  contents: GenericStreamFieldType

  """The ID of the object"""
  id: ID!
  bookmarks: [InstrumentBookmarkNode]
  type: InstrumentTypeNode
  language: String
  highlights: [HighlightNode!]!
  path: String!
}

type InstrumentTypeNode implements Node {
  """The ID of the object"""
  id: ID!
  name: String!
  category: InstrumentCategoryNode
  type: String!
}

type InstrumentCategoryNode implements Node {
  """The ID of the object"""
  id: ID!
  name: String!
  background: String!
  foreground: String!
  types: [InstrumentTypeNode]
}

type ModuleCategoryNode implements Node {
  """The ID of the object"""
  id: ID!
  name: String!
  filterAttributeType: BooksModuleCategoryFilterAttributeTypeChoices!

  """Order in the Dropdown List"""
  order: Int!
  moduleSet(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, slug_Icontains: String, slug_In: [String], title: String, title_Icontains: String, title_In: [String]): ModuleNodeConnection!
}

"""An enumeration."""
enum BooksModuleCategoryFilterAttributeTypeChoices {
  """All"""
  ALL

  """Exact"""
  EXACT
}

type AssignmentNode implements Node {
  """The ID of the object"""
  id: ID!
  created: DateTime!
  modified: DateTime!
  title: String!
  assignment: String!
  solution: String
  deleted: Boolean!
  owner: PrivateUserNode
  module: ModuleNode!
  userCreated: Boolean!
  taskbaseId: String
  submissions: [StudentSubmissionNode]
  submission: StudentSubmissionNode
  path: String!
}

"""
The `DateTime` scalar type represents a DateTime
value as specified by
[iso8601](https://en.wikipedia.org/wiki/ISO_8601).
"""
scalar DateTime

type StudentSubmissionNode implements Node {
  """The ID of the object"""
  id: ID!
  created: DateTime!
  modified: DateTime!
  text: String!
  document: String!
  assignment: AssignmentNode!
  student: PrivateUserNode!
  final: Boolean!
  submissionFeedback: SubmissionFeedbackNode
}

type SubmissionFeedbackNode implements Node {
  created: DateTime!
  modified: DateTime!
  text: String!
  teacher: PrivateUserNode!
  studentSubmission: StudentSubmissionNode!
  final: Boolean!

  """The ID of the object"""
  id: ID!
}

type ObjectiveGroupNode implements Node {
  """The ID of the object"""
  id: ID!
  title: ObjectivesObjectiveGroupTitleChoices
  module: ModuleNode!
  hiddenFor: [SchoolClassNode]
  objectives: [ObjectiveNode]
  pk: Int
  displayTitle: String
}

"""An enumeration."""
enum ObjectivesObjectiveGroupTitleChoices {
  """Sprache & Kommunikation"""
  LANGUAGE_COMMUNICATION

  """Gesellschaft"""
  SOCIETY

  """Überfachliche Lernziele"""
  INTERDISCIPLINARY
}

type ObjectiveNode implements Node {
  """The ID of the object"""
  id: ID!
  text: String!
  group: ObjectiveGroupNode!
  owner: PrivateUserNode
  hiddenFor: [SchoolClassNode]
  visibleFor: [SchoolClassNode]
  order: Int
  hiddenForSnapshots(offset: Int, before: String, after: String, first: Int, last: Int): SnapshotNodeConnection!
  pk: Int
  userCreated: Boolean
  mine: Boolean
}

type SnapshotNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [SnapshotNodeEdge]!
}

"""A Relay edge containing a `SnapshotNode` and its cursor."""
type SnapshotNodeEdge {
  """The item at the end of the edge"""
  node: SnapshotNode

  """A cursor for use in pagination"""
  cursor: String!
}

type SnapshotNode implements Node {
  """The ID of the object"""
  id: ID!
  module: ModuleNode!
  chapters: [SnapshotChapterNode]
  hiddenContentBlocks(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ContentBlockNodeConnection!
  created: DateTime!
  creator: String!
  shared: Boolean!
  objectiveGroups: [SnapshotObjectiveGroupNode]
  hiddenObjectives(offset: Int, before: String, after: String, first: Int, last: Int, text: String): ObjectiveNodeConnection!
  title: String
  metaTitle: String
  heroImage: String
  changes: SnapshotChangesNode
  mine: Boolean
}

type SnapshotChapterNode implements Node & ChapterInterface {
  """The ID of the object"""
  id: ID!
  description: String
  title: String
  contentBlocks: [SnapshotContentBlockNode]
  descriptionHidden: Boolean
  titleHidden: Boolean
}

type SnapshotContentBlockNode implements Node & ContentBlockInterface {
  """The ID of the object"""
  id: ID!
  title: String
  contents: GenericStreamFieldType
  type: String!
  hidden: Boolean
}

type ContentBlockNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [ContentBlockNodeEdge]!
}

"""A Relay edge containing a `ContentBlockNode` and its cursor."""
type ContentBlockNodeEdge {
  """The item at the end of the edge"""
  node: ContentBlockNode

  """A cursor for use in pagination"""
  cursor: String!
}

type SnapshotObjectiveGroupNode implements Node {
  """The ID of the object"""
  id: ID!
  title: String!
  hidden: Boolean!
  displayTitle: String!
  objectives: [SnapshotObjectiveNode]!
}

type SnapshotObjectiveNode implements Node {
  """The ID of the object"""
  id: ID!
  hidden: Boolean!
  text: String!
}

type ObjectiveNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [ObjectiveNodeEdge]!
}

"""A Relay edge containing a `ObjectiveNode` and its cursor."""
type ObjectiveNodeEdge {
  """The item at the end of the edge"""
  node: ObjectiveNode

  """A cursor for use in pagination"""
  cursor: String!
}

type SnapshotChangesNode {
  hiddenObjectives: Int!
  newObjectives: Int!
  hiddenContentBlocks: Int!
  newContentBlocks: Int!
}

type AnswerNode implements Node {
  """The ID of the object"""
  id: ID!
  owner: PrivateUserNode!
  data: JSONString!
  survey: SurveyNode!
  pk: Int
}

"""
Allows use of a JSON String for input / output from the GraphQL schema.

Use of this type is *not recommended* as you lose the benefits of having a defined, static
schema (one of the key benefits of GraphQL).
"""
scalar JSONString

type ContentBlockBookmarkNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [ContentBlockBookmarkNodeEdge]!
}

"""A Relay edge containing a `ContentBlockBookmarkNode` and its cursor."""
type ContentBlockBookmarkNodeEdge {
  """The item at the end of the edge"""
  node: ContentBlockBookmarkNode

  """A cursor for use in pagination"""
  cursor: String!
}

type ChapterBookmarkNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [ChapterBookmarkNodeEdge]!
}

"""A Relay edge containing a `ChapterBookmarkNode` and its cursor."""
type ChapterBookmarkNodeEdge {
  """The item at the end of the edge"""
  node: ChapterBookmarkNode

  """A cursor for use in pagination"""
  cursor: String!
}

union BookmarkNode = ContentBlockBookmarkNode | ModuleBookmarkNode | ChapterBookmarkNode | InstrumentBookmarkNode

type AnswerNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [AnswerNodeEdge]!
}

"""A Relay edge containing a `AnswerNode` and its cursor."""
type AnswerNodeEdge {
  """The item at the end of the edge"""
  node: AnswerNode

  """A cursor for use in pagination"""
  cursor: String!
}

type SurveyNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [SurveyNodeEdge]!
}

"""A Relay edge containing a `SurveyNode` and its cursor."""
type SurveyNodeEdge {
  """The item at the end of the edge"""
  node: SurveyNode

  """A cursor for use in pagination"""
  cursor: String!
}

type ProjectNode implements Node {
  """The ID of the object"""
  id: ID!
  title: String!
  description: String
  slug: String!
  objectives: String!
  appearance: String!
  student: PrivateUserNode!
  final: Boolean!
  schoolClass: SchoolClassNode
  entries: [ProjectEntryNode]
  pk: Int
  entriesCount: Int
  owner: PublicUserNode
}

type ProjectEntryNode implements Node {
  documentUrl: String!
  description: String!
  created: DateTime!
  project: ProjectNode!

  """The ID of the object"""
  id: ID!
}

union TopicOr404Node = TopicNode | NotFound

type NotFound {
  reason: String
}

type TopicConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [TopicEdge]!
  nodes: [TopicNode]
}

"""A Relay edge containing a `Topic` and its cursor."""
type TopicEdge {
  """The item at the end of the edge"""
  node: TopicNode

  """A cursor for use in pagination"""
  cursor: String!
}

type ModuleConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [ModuleEdge]!
  nodes: [ModuleNode]
}

"""A Relay edge containing a `Module` and its cursor."""
type ModuleEdge {
  """The item at the end of the edge"""
  node: ModuleNode

  """A cursor for use in pagination"""
  cursor: String!
}

type ChapterNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [ChapterNodeEdge]!
}

"""A Relay edge containing a `ChapterNode` and its cursor."""
type ChapterNodeEdge {
  """The item at the end of the edge"""
  node: ChapterNode

  """A cursor for use in pagination"""
  cursor: String!
}

type ObjectiveGroupNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [ObjectiveGroupNodeEdge]!
}

"""A Relay edge containing a `ObjectiveGroupNode` and its cursor."""
type ObjectiveGroupNodeEdge {
  """The item at the end of the edge"""
  node: ObjectiveGroupNode

  """A cursor for use in pagination"""
  cursor: String!
}

type RoomEntryNode implements Node {
  """The ID of the object"""
  id: ID!
  title: String!
  description: String
  slug: String!
  room: RoomNode!
  author: PublicUserNode

  """"""
  contents: GenericStreamFieldType
  comments: [CommentNode]
  pk: Int
}

type RoomNode implements Node {
  """The ID of the object"""
  id: ID!
  title: String!
  description: String
  slug: String!
  schoolClass: SchoolClassNode!
  appearance: String!
  userCreated: Boolean!
  restricted: Boolean!
  roomEntries(offset: Int, before: String, after: String, first: Int, last: Int, slug: String): RoomEntryNodeConnection!
  pk: Int
  entryCount: Int
}

type RoomEntryNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [RoomEntryNodeEdge]!
}

"""A Relay edge containing a `RoomEntryNode` and its cursor."""
type RoomEntryNodeEdge {
  """The item at the end of the edge"""
  node: RoomEntryNode

  """A cursor for use in pagination"""
  cursor: String!
}

type CommentNode implements Node {
  text: String!
  owner: PublicUserNode
  created: DateTime!

  """The ID of the object"""
  id: ID!
}

type PrivateUserNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [PrivateUserNodeEdge]!
}

"""A Relay edge containing a `PrivateUserNode` and its cursor."""
type PrivateUserNodeEdge {
  """The item at the end of the edge"""
  node: PrivateUserNode

  """A cursor for use in pagination"""
  cursor: String!
}

type InstrumentNodeConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!

  """Contains the nodes in this connection."""
  edges: [InstrumentNodeEdge]!
}

"""A Relay edge containing a `InstrumentNode` and its cursor."""
type InstrumentNodeEdge {
  """The item at the end of the edge"""
  node: InstrumentNode

  """A cursor for use in pagination"""
  cursor: String!
}

type ActivityNode {
  topics: [TopicNode!]!
  instruments: [InstrumentNode!]!
}

"""Debugging information for the current query."""
type DjangoDebug {
  """Executed SQL queries for this API query."""
  sql: [DjangoDebugSQL]

  """Raise exceptions for this API query."""
  exceptions: [DjangoDebugException]
}

"""Represents a single database query made to a Django managed DB."""
type DjangoDebugSQL {
  """The type of database being used (e.g. postrgesql, mysql, sqlite)."""
  vendor: String!

  """The Django database alias (e.g. 'default')."""
  alias: String!

  """The actual SQL sent to this database."""
  sql: String

  """Duration of this database query in seconds."""
  duration: Float!

  """The raw SQL of this query, without params."""
  rawSql: String!

  """JSON encoded database query parameters."""
  params: String!

  """Start time of this database query."""
  startTime: Float!

  """Stop time of this database query."""
  stopTime: Float!

  """Whether this database query took more than 10 seconds."""
  isSlow: Boolean!

  """Whether this database query was a SELECT."""
  isSelect: Boolean!

  """Postgres transaction ID if available."""
  transId: String

  """Postgres transaction status if available."""
  transStatus: String

  """Postgres isolation level if available."""
  isoLevel: String

  """Postgres connection encoding if available."""
  encoding: String
}

"""Represents a single exception raised."""
type DjangoDebugException {
  """The class of the exception"""
  excType: String!

  """The message of the exception"""
  message: String!

  """The stack trace"""
  stack: String!
}

type Mutation {
  spellCheck(input: SpellCheckInput!): SpellCheckPayload
  addNote(input: AddNoteInput!): AddNotePayload
  addHighlight(input: AddHighlightInput!): AddHighlightPayload
  addContentHighlight(input: AddContentHighlightInput!): AddContentHighlightPayload
  deleteHighlight(input: DeleteHighlightInput!): DeleteHighlightPayload
  updateHighlight(input: UpdateHighlightInput!): UpdateHighlightPayload
  updateNote(input: UpdateNoteInput!): UpdateNotePayload
  updateContentBookmark(input: UpdateContentBookmarkInput!): UpdateContentBookmarkPayload
  updateChapterBookmark(input: UpdateChapterBookmarkInput!): UpdateChapterBookmarkPayload
  updateModuleBookmark(input: UpdateModuleBookmarkInput!): UpdateModuleBookmarkPayload
  updateInstrumentBookmark(input: UpdateInstrumentBookmarkInput!): UpdateInstrumentBookmarkPayload
  updateAnswer(input: UpdateAnswerInput!): UpdateAnswerPayload
  updatePassword(input: UpdatePasswordInput!): UpdatePasswordPayload
  updateAvatar(input: UpdateAvatarInput!): UpdateAvatarPayload
  updateSetting(input: UpdateSettingInput!): UpdateSettingPayload
  joinClass(input: JoinClassInput!): JoinClassPayload
  addRemoveMember(input: AddRemoveMemberInput!): AddRemoveMemberPayload
  updateSchoolClass(input: UpdateSchoolClassInput!): UpdateSchoolClassPayload
  createSchoolClass(input: CreateSchoolClassInput!): CreateSchoolClassPayload
  updateOnboardingProgress: UpdateOnboardingProgress
  createTeam(input: CreateTeamInput!): CreateTeamPayload
  joinTeam(input: JoinTeamInput!): JoinTeamPayload
  updateTeam(input: UpdateTeamInput!): UpdateTeamPayload
  leaveTeam: LeaveTeam
  addProject(input: AddProjectInput!): AddProjectPayload
  updateProject(input: UpdateProjectInput!): UpdateProjectPayload
  deleteProject(input: DeleteProjectInput!): DeleteProjectPayload
  addProjectEntry(input: AddProjectEntryInput!): AddProjectEntryPayload
  updateProjectEntry(input: UpdateProjectEntryInput!): UpdateProjectEntryPayload
  deleteProjectEntry(input: DeleteProjectEntryInput!): DeleteProjectEntryPayload
  updateProjectSharedState(input: UpdateProjectSharedStateInput!): UpdateProjectSharedStatePayload
  logout: Logout
  coupon(input: CouponInput!): CouponPayload
  updateObjectiveVisibility(input: UpdateObjectiveVisibilityInput!): UpdateObjectiveVisibilityPayload
  updateObjectiveGroupVisibility(input: UpdateObjectiveGroupVisibilityInput!): UpdateObjectiveGroupVisibilityPayload
  addObjective(input: AddObjectiveInput!): AddObjectivePayload
  deleteObjective(input: DeleteObjectiveInput!): DeleteObjectivePayload
  updateAssignment(input: UpdateAssignmentInput!): UpdateAssignmentPayload
  updateSubmissionFeedback(input: UpdateSubmissionFeedbackInput!): UpdateSubmissionFeedbackPayload
  updateRoom(input: UpdateRoomInput!): UpdateRoomPayload
  addRoom(input: AddRoomInput!): AddRoomPayload
  deleteRoom(input: DeleteRoomInput!): DeleteRoomPayload
  addRoomEntry(input: AddRoomEntryInput!): AddRoomEntryPayload
  addModuleRoomEntry(input: AddModuleRoomEntryInput!): AddModuleRoomEntryPayload
  deleteRoomEntry(input: DeleteRoomEntryInput!): DeleteRoomEntryPayload
  updateRoomEntry(input: UpdateRoomEntryInput!): UpdateRoomEntryPayload
  addComment(input: AddCommentInput!): AddCommentPayload
  updateRoomVisibility(input: UpdateRoomVisibilityInput!): UpdateRoomVisibilityPayload
  mutateContentBlock(input: MutateContentBlockInput!): MutateContentBlockPayload
  addContentBlock(input: AddContentBlockInput!): AddContentBlockPayload
  deleteContentBlock(input: DeleteContentBlockInput!): DeleteContentBlockPayload
  duplicateContentBlock(input: DuplicateContentBlockInput!): DuplicateContentBlockPayload
  updateSolutionVisibility(input: UpdateSolutionVisibilityInput!): UpdateSolutionVisibilityPayload
  updateLastModule(input: UpdateLastModuleInput!): UpdateLastModulePayload
  updateLastTopic(input: UpdateLastTopicInput!): UpdateLastTopicPayload
  updateLastModuleLevel(input: UpdateLastModuleLevelInput!): UpdateLastModuleLevelPayload
  updateChapterVisibility(input: UpdateChapterVisibilityInput!): UpdateChapterVisibilityPayload
  syncModuleVisibility(input: SyncModuleVisibilityInput!): SyncModuleVisibilityPayload
  createSnapshot(input: CreateSnapshotInput!): CreateSnapshotPayload
  applySnapshot(input: ApplySnapshotInput!): ApplySnapshotPayload
  shareSnapshot(input: ShareSnapshotInput!): ShareSnapshotPayload
  updateSnapshot(input: UpdateSnapshotInput!): UpdateSnapshotPayload
  deleteSnapshot(input: DeleteSnapshotInput!): DeleteSnapshotPayload
  _debug: DjangoDebug
}

type SpellCheckPayload {
  results: [SpellCheckStepNode]
  correct: Boolean
  clientMutationId: String
}

type SpellCheckStepNode {
  sentence: String
  offset: Int
  sentenceOffset: Int
  length: Int
  affected: String
  corrected: String
}

input SpellCheckInput {
  text: String!
  assignment: ID!
  clientMutationId: String
}

type AddNotePayload {
  note: NoteNode
  clientMutationId: String
}

input AddNoteInput {
  note: AddNoteArgument
  clientMutationId: String
}

input AddNoteArgument {
  content: UUID
  block: String
  type: String
  parent: ID
  text: String!
}

type AddHighlightPayload {
  highlight: HighlightNode
  clientMutationId: String
}

input AddHighlightInput {
  highlight: AddHighlightArgument
  clientMutationId: String
}

input AddHighlightArgument {
  page: String!
  paragraphIndex: Int!
  text: String!
  startPosition: Int!
  selectionLength: Int!
  color: String!
}

type AddContentHighlightPayload {
  highlight: HighlightNode
  clientMutationId: String
}

input AddContentHighlightInput {
  highlight: AddContentHighlightArgument
  clientMutationId: String
}

input AddContentHighlightArgument {
  page: String!
  paragraphIndex: Int!
  text: String!
  startPosition: Int!
  selectionLength: Int!
  color: String!
  contentIndex: Int!
  contentUuid: UUID!
}

type DeleteHighlightPayload {
  success: Boolean!
  clientMutationId: String
}

input DeleteHighlightInput {
  id: ID!
  clientMutationId: String
}

type UpdateHighlightPayload {
  highlight: HighlightNode
  clientMutationId: String
}

input UpdateHighlightInput {
  color: String
  note: String
  id: ID!
  clientMutationId: String
}

type UpdateNotePayload {
  note: NoteNode
  clientMutationId: String
}

input UpdateNoteInput {
  note: UpdateNoteArgument
  clientMutationId: String
}

input UpdateNoteArgument {
  id: ID!
  text: String!
}

type UpdateContentBookmarkPayload {
  success: Boolean
  errors: String
  clientMutationId: String
}

input UpdateContentBookmarkInput {
  uuid: UUID!
  contentBlock: ID!
  bookmarked: Boolean!
  clientMutationId: String
}

type UpdateChapterBookmarkPayload {
  success: Boolean
  clientMutationId: String
}

input UpdateChapterBookmarkInput {
  chapter: ID!
  bookmarked: Boolean!
  clientMutationId: String
}

type UpdateModuleBookmarkPayload {
  success: Boolean
  clientMutationId: String
}

input UpdateModuleBookmarkInput {
  module: String!
  bookmarked: Boolean!
  clientMutationId: String
}

type UpdateInstrumentBookmarkPayload {
  success: Boolean
  clientMutationId: String
}

input UpdateInstrumentBookmarkInput {
  uuid: UUID!
  instrument: String!
  bookmarked: Boolean!
  clientMutationId: String
}

type UpdateAnswerPayload {
  answer: AnswerNode
  clientMutationId: String
}

input UpdateAnswerInput {
  answer: UpdateAnswerArgument
  clientMutationId: String
}

input UpdateAnswerArgument {
  surveyId: ID!
  data: String!
}

type UpdatePasswordPayload {
  success: Boolean
  errors: [UpdateError]
  clientMutationId: String
}

type UpdateError {
  field: String
  errors: [FieldError]
}

type FieldError {
  code: String
}

input UpdatePasswordInput {
  passwordInput: PasswordUpdateInput
  clientMutationId: String
}

input PasswordUpdateInput {
  oldPassword: String
  newPassword: String
}

type UpdateAvatarPayload {
  success: Boolean
  errors: [UpdateError]
  clientMutationId: String
}

input UpdateAvatarInput {
  avatarUrl: String
  clientMutationId: String
}

type UpdateSettingPayload {
  success: Boolean
  errors: [UpdateError]
  clientMutationId: String
}

input UpdateSettingInput {
  id: ID!
  clientMutationId: String
}

type JoinClassPayload {
  success: Boolean
  schoolClass: SchoolClassNode
  clientMutationId: String
}

input JoinClassInput {
  code: String!
  clientMutationId: String
}

type AddRemoveMemberPayload {
  success: Boolean
  clientMutationId: String
}

input AddRemoveMemberInput {
  member: ID!
  schoolClass: ID!
  active: Boolean!
  clientMutationId: String
}

type UpdateSchoolClassPayload {
  success: Boolean
  schoolClass: SchoolClassNode
  clientMutationId: String
}

input UpdateSchoolClassInput {
  id: ID!
  name: String
  clientMutationId: String
}

type CreateSchoolClassPayload {
  result: CreateSchoolClassResult
  clientMutationId: String
}

union CreateSchoolClassResult = SchoolClassNode | DuplicateName

type DuplicateName implements FailureNode {
  reason: String
}

interface FailureNode {
  reason: String
}

input CreateSchoolClassInput {
  name: String
  clientMutationId: String
}

type UpdateOnboardingProgress {
  success: Boolean
}

type CreateTeamPayload {
  result: CreateTeamResult
  clientMutationId: String
}

union CreateTeamResult = TeamNode | DuplicateName

input CreateTeamInput {
  name: String!
  clientMutationId: String
}

type JoinTeamPayload {
  success: Boolean
  team: TeamNode
  clientMutationId: String
}

input JoinTeamInput {
  code: String!
  clientMutationId: String
}

type UpdateTeamPayload {
  success: Boolean
  team: TeamNode
  clientMutationId: String
}

input UpdateTeamInput {
  id: ID!
  name: String
  clientMutationId: String
}

type LeaveTeam {
  success: Boolean
}

type AddProjectPayload {
  errors: [String]
  project: ProjectNode
  clientMutationId: String
}

input AddProjectInput {
  project: AddProjectArgument
  clientMutationId: String
}

input AddProjectArgument {
  title: String
  description: String
  objectives: String
  appearance: String
}

type UpdateProjectPayload {
  errors: [String]
  project: ProjectNode
  clientMutationId: String
}

input UpdateProjectInput {
  project: UpdateProjectArgument
  clientMutationId: String
}

input UpdateProjectArgument {
  title: String
  description: String
  objectives: String
  appearance: String
  slug: String!
  final: Boolean
}

type DeleteProjectPayload {
  success: Boolean
  errors: [String]
  clientMutationId: String
}

input DeleteProjectInput {
  slug: String!
  clientMutationId: String
}

type AddProjectEntryPayload {
  errors: [String]
  projectEntry: ProjectEntryNode
  clientMutationId: String
}

input AddProjectEntryInput {
  projectEntry: AddProjectEntryArgument
  clientMutationId: String
}

input AddProjectEntryArgument {
  description: String
  documentUrl: String
  project: String!
}

type UpdateProjectEntryPayload {
  errors: [String]
  projectEntry: ProjectEntryNode
  clientMutationId: String
}

input UpdateProjectEntryInput {
  projectEntry: UpdateProjectEntryArgument
  clientMutationId: String
}

input UpdateProjectEntryArgument {
  description: String
  documentUrl: String
  id: ID!
}

type DeleteProjectEntryPayload {
  success: Boolean
  errors: [String]
  clientMutationId: String
}

input DeleteProjectEntryInput {
  id: ID!
  clientMutationId: String
}

type UpdateProjectSharedStatePayload {
  success: Boolean
  shared: Boolean
  errors: [String]
  clientMutationId: String
}

input UpdateProjectSharedStateInput {
  slug: String
  shared: Boolean
  clientMutationId: String
}

type Logout {
  success: Boolean
}

type CouponPayload {
  result: RedeemCouponResult
  clientMutationId: String
}

union RedeemCouponResult = Success | InvalidCoupon

type Success implements SuccessNode {
  message: String
}

interface SuccessNode {
  message: String
}

type InvalidCoupon implements FailureNode {
  reason: String
}

input CouponInput {
  couponCode: String
  clientMutationId: String
}

type UpdateObjectiveVisibilityPayload {
  objective: ObjectiveNode
  clientMutationId: String
}

input UpdateObjectiveVisibilityInput {
  """The ID of the objective"""
  id: ID!
  visibility: [UserGroupBlockVisibility]
  clientMutationId: String
}

input UserGroupBlockVisibility {
  schoolClassId: ID!
  hidden: Boolean!
}

type UpdateObjectiveGroupVisibilityPayload {
  objectiveGroup: ObjectiveGroupNode
  clientMutationId: String
}

input UpdateObjectiveGroupVisibilityInput {
  """The ID of the objective group"""
  id: ID!
  visibility: [UserGroupBlockVisibility]
  clientMutationId: String
}

type AddObjectivePayload {
  objective: ObjectiveNode
  clientMutationId: String
}

input AddObjectiveInput {
  objective: AddObjectiveArgument
  clientMutationId: String
}

input AddObjectiveArgument {
  text: String!
  objectiveGroup: ID
}

type DeleteObjectivePayload {
  success: Boolean
  clientMutationId: String
}

input DeleteObjectiveInput {
  id: ID!
  clientMutationId: String
}

type UpdateAssignmentPayload {
  updatedAssignment: AssignmentNode
  submission: StudentSubmissionNode
  successful: Boolean
  errors: [String]
  clientMutationId: String
}

input UpdateAssignmentInput {
  assignment: AssignmentInput
  clientMutationId: String
}

input AssignmentInput {
  id: ID!
  answer: String!
  document: String
  final: Boolean
}

type UpdateSubmissionFeedbackPayload {
  updatedSubmissionFeedback: SubmissionFeedbackNode
  successful: Boolean
  errors: [String]
  clientMutationId: String
}

input UpdateSubmissionFeedbackInput {
  submissionFeedback: SubmissionFeedbackInput
  clientMutationId: String
}

input SubmissionFeedbackInput {
  id: ID
  studentSubmission: ID!
  text: String!
  final: Boolean
}

type UpdateRoomPayload {
  errors: [String]
  room: RoomNode
  clientMutationId: String
}

input UpdateRoomInput {
  room: UpdateRoomArgument
  clientMutationId: String
}

input UpdateRoomArgument {
  title: String
  description: String
  schoolClass: SchoolClassInput
  appearance: String
  id: ID!
}

input SchoolClassInput {
  id: ID
  name: String
}

type AddRoomPayload {
  errors: [String]
  room: RoomNode
  clientMutationId: String
}

input AddRoomInput {
  room: AddRoomArgument
  clientMutationId: String
}

input AddRoomArgument {
  title: String
  description: String
  schoolClass: SchoolClassInput
  appearance: String
}

type DeleteRoomPayload {
  success: Boolean
  errors: [String]
  clientMutationId: String
}

input DeleteRoomInput {
  id: ID!
  clientMutationId: String
}

type AddRoomEntryPayload {
  roomEntry: RoomEntryNode
  errors: [String]
  clientMutationId: String
}

input AddRoomEntryInput {
  roomEntry: AddRoomEntryArgument
  clientMutationId: String
}

input AddRoomEntryArgument {
  title: String!
  contents: [ContentElementInput]
  roomSlug: String!
}

input ContentElementInput {
  id: String
  type: InputTypes!
  value: ContentElementValueInput
  contents: [ContentElementInput]
}

enum InputTypes {
  text_block
  assignment
  image_block
  image_url_block
  link_block
  video_block
  document_block
  content_list_item
  subtitle
  readonly
}

input ContentElementValueInput {
  """To be used for link_block, text_block types"""
  text: String

  """To be used for link, image_block types"""
  url: String

  """To be used for basic_knowledge type"""
  description: String

  """To be used for image_block, assignment type"""
  title: String

  """To be used for assignment type"""
  assignment: String

  """To be used for assignment type"""
  id: String
}

type AddModuleRoomEntryPayload {
  roomEntry: RoomEntryNode
  errors: [String]
  clientMutationId: String
}

input AddModuleRoomEntryInput {
  roomEntry: AddModuleRoomEntryArgument
  clientMutationId: String
}

input AddModuleRoomEntryArgument {
  title: String!
  contents: [ContentElementInput]
  roomSlug: String!
  schoolClass: String!
}

type DeleteRoomEntryPayload {
  success: Boolean
  roomSlug: String
  roomId: ID
  errors: [String]
  clientMutationId: String
}

input DeleteRoomEntryInput {
  slug: String!
  clientMutationId: String
}

type UpdateRoomEntryPayload {
  roomEntry: RoomEntryNode
  errors: [String]
  clientMutationId: String
}

input UpdateRoomEntryInput {
  roomEntry: UpdateRoomEntryArgument
  clientMutationId: String
}

input UpdateRoomEntryArgument {
  title: String!
  contents: [ContentElementInput]
  slug: String!
}

type AddCommentPayload {
  success: Boolean
  comment: CommentNode
  clientMutationId: String
}

input AddCommentInput {
  comment: String!
  roomEntry: ID!
  clientMutationId: String
}

type UpdateRoomVisibilityPayload {
  success: Boolean
  room: RoomNode
  clientMutationId: String
}

input UpdateRoomVisibilityInput {
  id: ID!
  restricted: Boolean!
  clientMutationId: String
}

type MutateContentBlockPayload {
  contentBlock: ContentBlockNode
  clientMutationId: String
}

input MutateContentBlockInput {
  id: ID!
  contentBlock: ContentBlockInput
  clientMutationId: String
}

input ContentBlockInput {
  title: String
  type: String
  contents: [ContentElementInput]
  visibility: [UserGroupBlockVisibility]
}

type AddContentBlockPayload {
  newContentBlock: ContentBlockNode
  errors: [String]
  clientMutationId: String
}

input AddContentBlockInput {
  contentBlock: ContentBlockInput
  parent: ID
  after: ID
  clientMutationId: String
}

type DeleteContentBlockPayload {
  success: Boolean
  errors: String
  clientMutationId: String
}

input DeleteContentBlockInput {
  id: ID!
  clientMutationId: String
}

type DuplicateContentBlockPayload {
  contentBlock: ContentBlockNode
  clientMutationId: String
}

input DuplicateContentBlockInput {
  id: ID!
  clientMutationId: String
}

type UpdateSolutionVisibilityPayload {
  success: Boolean
  solutionsEnabled: Boolean
  errors: [String]
  clientMutationId: String
}

input UpdateSolutionVisibilityInput {
  slug: String
  enabled: Boolean
  clientMutationId: String
}

type UpdateLastModulePayload {
  lastModule: ModuleNode
  clientMutationId: String
}

input UpdateLastModuleInput {
  id: ID
  clientMutationId: String
}

type UpdateLastTopicPayload {
  topic: TopicNode
  clientMutationId: String
}

input UpdateLastTopicInput {
  id: ID
  clientMutationId: String
}

type UpdateLastModuleLevelPayload {
  user: PrivateUserNode
  clientMutationId: String
}

input UpdateLastModuleLevelInput {
  id: ID
  clientMutationId: String
}

type UpdateChapterVisibilityPayload {
  chapter: ChapterNode
  clientMutationId: String
}

input UpdateChapterVisibilityInput {
  id: ID!
  visibility: [UserGroupBlockVisibility]
  type: String!
  clientMutationId: String
}

type SyncModuleVisibilityPayload {
  success: Boolean
  clientMutationId: String
}

input SyncModuleVisibilityInput {
  module: String!
  templateSchoolClass: ID!
  schoolClass: ID!
  clientMutationId: String
}

type CreateSnapshotPayload {
  snapshot: SnapshotNode
  success: Boolean
  clientMutationId: String
}

input CreateSnapshotInput {
  module: String!
  selectedClass: ID!
  clientMutationId: String
}

type ApplySnapshotPayload {
  success: Boolean
  module: ModuleNode
  clientMutationId: String
}

input ApplySnapshotInput {
  snapshot: ID!
  selectedClass: ID!
  clientMutationId: String
}

type ShareSnapshotPayload {
  success: Boolean!
  snapshot: SnapshotNode
  clientMutationId: String
}

input ShareSnapshotInput {
  snapshot: ID!
  shared: Boolean!
  clientMutationId: String
}

type UpdateSnapshotPayload {
  snapshot: UpdateSnapshotResult
  clientMutationId: String
}

union UpdateSnapshotResult = SnapshotNode | NotOwner

type NotOwner implements FailureNode {
  reason: String
}

input UpdateSnapshotInput {
  id: ID!
  title: String
  clientMutationId: String
}

type DeleteSnapshotPayload {
  result: DeleteSnapshotResult
  clientMutationId: String
}

union DeleteSnapshotResult = Success | NotOwner

input DeleteSnapshotInput {
  id: ID!
  clientMutationId: String
}