<commit_before>define (require) ->
  $ = require('jquery')
  _ = require('underscore')
  Backbone = require('backbone')

  MEDIA_TYPES =
    'application/vnd.org.cnx.collection' : 'book'
    'application/vnd.org.cnx.module': 'module'

  CONTENT_URI = "#{location.protocol}//#{location.hostname}:6543/contents"

  class CurrentPage extends Backbone.Model
    url: () -> "#{CONTENT_URI}/#{@id}"

    defaults:
      title: 'Untitled'
      content: 'No content'
      authors: []

    parse: (response, options) ->
      # jQuery can not build a jQuery object with <head> or <body> tags,
      # and will instead move all elements in them up one level.
      # Use a regex to extract everything in the body and put it into a div instead.
      $body = $('<div>' + response.content.replace(/^[\s\S]*<body.*?>|<\/body>[\s\S]*$/g, '') + '</div>')
      $body.find('.title').eq(0).remove()
      response.content = $body.html()

      return response

  return class Content extends Backbone.Model
    url: () -> "#{CONTENT_URI}/#{@id}"

    defaults:
      title: 'Untitled Book'
      pages: 1
      authors: []
      currentPage: new CurrentPage()

    toJSON: () ->
      currentPage = @get('currentPage').toJSON()
      json = super()
      json.currentPage = currentPage
      return json

    initialize: (options = {}) ->
      @fetch
        success: () => @setup(options.page)

    setup: (page) ->
      type = MEDIA_TYPES[@get('mediaType')]
      @set('type', type)

      if type is 'book'
        @setupToc()
        @setPage(page or 1) # Default to page 1
      else
        currentPage = @get('currentPage')
        currentPage.id = @id
        currentPage.fetch()

    # Create a flat collection to store all the pages
    setupToc: () ->
      toc = new Backbone.Collection()

      _.each @get('tree').contents, (item, index, contents) ->
        if item.contents
          _.each item.contents, (module, ind, subcol) ->
            module.parent = index # Module parents are numbered by their position in the tree
            toc.add(module)
        else
          toc.add(item)

      @set('toc', toc)
      @set('pages', toc.models.length)

    setPage: (num) ->
      if num < 1 then num = 1
      if num > @pages then num = @pages
      if not num then return

      @set('page', num)

      currentPage = @get('currentPage')
      currentPage.clear({silent: true}).set(currentPage.defaults) # Reset the current page
      contents = @get('toc').at(num-1).toJSON()
      currentPage.id = contents.id
      currentPage.fetch
        success: (model, response, options) ->
          currentPage.set('title', contents.title) if contents.title

    nextPage: () ->
      currentPage = @get('currentPage')
      page = @get('page')

      # Show the next page if there is one<commit_msg>Load subcollections of aritrary depth<commit_after>define (require) ->
  $ = require('jquery')
  _ = require('underscore')
  Backbone = require('backbone')

  MEDIA_TYPES =
    'application/vnd.org.cnx.collection' : 'book'
    'application/vnd.org.cnx.module': 'module'

  CONTENT_URI = "#{location.protocol}//#{location.hostname}:6543/contents"

  class CurrentPage extends Backbone.Model
    url: () -> "#{CONTENT_URI}/#{@id}"

    defaults:
      title: 'Untitled'
      content: 'No content'
      authors: []

    parse: (response, options) ->
      # jQuery can not build a jQuery object with <head> or <body> tags,
      # and will instead move all elements in them up one level.
      # Use a regex to extract everything in the body and put it into a div instead.
      $body = $('<div>' + response.content.replace(/^[\s\S]*<body.*?>|<\/body>[\s\S]*$/g, '') + '</div>')
      $body.find('.title').eq(0).remove()
      response.content = $body.html()

      return response

  return class Content extends Backbone.Model
    url: () -> "#{CONTENT_URI}/#{@id}"

    defaults:
      title: 'Untitled Book'
      pages: 1
      authors: []
      currentPage: new CurrentPage()

    toJSON: () ->
      currentPage = @get('currentPage').toJSON()
      json = super()
      json.currentPage = currentPage
      return json

    initialize: (options = {}) ->
      @fetch
        success: () => @setup(options.page)

    setup: (page) ->
      type = MEDIA_TYPES[@get('mediaType')]
      @set('type', type)

      if type is 'book'
        @setupToc()
        @setPage(page or 1) # Default to page 1
      else
        currentPage = @get('currentPage')
        currentPage.id = @id
        currentPage.fetch()

    # Create a flat collection to store all the pages
    setupToc: () ->
      toc = new Backbone.Collection()
      index = 0

      traverse = (o, sub) ->
        if typeof o isnt 'object' then return
        for item in o.contents
          if item.contents
            traverse(item, true)
            index++
          else
            if sub then item.parent = index # Item parents are numbered by their position in the tree
            toc.add(item)

      traverse(@get('tree'))
      @set('toc', toc)
      @set('pages', toc.models.length)

    setPage: (num) ->
      if num < 1 then num = 1
      if num > @pages then num = @pages
      if not num then return

      @set('page', num)

      currentPage = @get('currentPage')
      currentPage.clear({silent: true}).set(currentPage.defaults) # Reset the current page
      contents = @get('toc').at(num-1).toJSON()
      currentPage.id = contents.id
      currentPage.fetch
        success: (model, response, options) ->
          currentPage.set('title', contents.title) if contents.title

    nextPage: () ->
      currentPage = @get('currentPage')
      page = @get('page')

      # Show the next page if there is one
{'fraction_non_alphanumeric': 0.14330874604847207, 'fraction_numerical': 0.004039339655778012, 'mean_word_length': 2.3718176435760805, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2994713', 'n_tokens_mistral': 1776, 'n_tokens_neox': 1709, 'n_words': 477}