text:
import gettext as gettext_module
import os
import stat
import unittest
from io import StringIO
from pathlib import Path
from subprocess import run
from unittest import mock

from django.core.management import CommandError, call_command, execute_from_command_line
from django.core.management.commands.makemessages import Command as MakeMessagesCommand
from django.core.management.utils import find_command
from django.test import SimpleTestCase, override_settings
from django.test.utils import captured_stderr, captured_stdout
from django.utils import translation
from django.utils.translation import gettext

from .utils import RunInTmpDirMixin, copytree

has_msgfmt = find_command("msgfmt")

@unittest.skipUnless(has_msgfmt, "msgfmt is mandatory for compilation tests")
class MessageCompilationTests(RunInTmpDirMixin, SimpleTestCase):

    work_subdir = "commands"

class PoFileTests(MessageCompilationTests):

    LOCALE = "es_AR"
    MO_FILE = "locale/%s/LC_MESSAGES/django.mo" % LOCALE
    MO_FILE_EN = "locale/en/LC_MESSAGES/django.mo"

    def test_bom_rejection(self):
        stderr = StringIO()
        with self.assertRaisesMessage(
            CommandError, "compilemessages generated one or more errors."
        ):
            call_command(
                "compilemessages", locale=[self.LOCALE], verbosity=0, stderr=stderr
            )
        self.assertIn("file has a BOM (Byte Order Mark)", stderr.getvalue())
        self.assertFalse(os.path.exists(self.MO_FILE))

    def test_no_write_access(self):
        mo_file_en = Path(self.MO_FILE_EN)
        err_buffer = StringIO()
        # Put file in read-only mode.
        old_mode = mo_file_en.stat().st_mode
        mo_file_en.chmod(stat.S_IREAD)
        # Ensure .po file is more recent than .mo file.
        mo_file_en.with_suffix(".po").touch()
        try:
            with self.assertRaisesMessage(
                CommandError, "compilemessages generated one or more errors."
            ):
                call_command(
                    "compilemessages", locale=["en"], stderr=err_buffer, verbosity=0
                )
            self.assertIn("not writable location", err_buffer.getvalue())
        finally:
            mo_file_en.chmod(old_mode)

    def test_no_compile_when_unneeded(self):
        mo_file_en = Path(self.MO_FILE_EN)
        mo_file_en.touch()
        stdout = StringIO()
        call_command("compilemessages", locale=["en"], stdout=stdout, verbosity=1)
        msg = "%s" is already compiled and up to date." % mo_file_en.with_suffix(".po")
        self.assertIn(msg, stdout.getvalue())

class PoFileContentsTests(MessageCompilationTests):
    # Ticket #11240

    LOCALE = "fr"
    MO_FILE = "locale/%s/LC_MESSAGES/django.mo" % LOCALE

    def test_percent_symbol_in_po_file(self):
        call_command("compilemessages", locale=[self.LOCALE], verbosity=0)
        self.assertTrue(os.path.exists(self.MO_FILE))

class MultipleLocaleCompilationTests(MessageCompilationTests):

    MO_FILE_HR = None
    MO_FILE_FR = None

    def setUp(self):
        super().setUp()
        localedir = os.path.join(self.test_dir, "locale")
        self.MO_FILE_HR = os.path.join(localedir, "hr/LC_MESSAGES/django.mo")
        self.MO_FILE_FR = os.path.join(localedir, "fr/LC_MESSAGES/django.mo")

    def test_one_locale(self):
        with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
            call_command("compilemessages", locale=["hr"], verbosity=0)

            self.assertTrue(os.path.exists(self.MO_FILE_HR))

    def test_multiple_locales(self):
        with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
            call_command("compilemessages", locale=["hr", "fr"], verbosity=0)

            self.assertTrue(os.path.exists(self.MO_FILE_HR))
            self.assertTrue(os.path.exists(self.MO_FILE_FR))

class ExcludedLocaleCompilationTests(MessageCompilationTests):

    work_subdir = "exclude"

    MO_FILE = "locale/%s/LC_MESSAGES/django.mo"

    def setUp(self):
        super().setUp()
        copytree("canned_locale", "locale")

    def test_command_help(self):
        with captured_stdout(), captured_stderr():
            # `call_command` bypasses the parser; by calling
            # `execute_from_command_line` with the help subcommand we
            # ensure that there are no issues with the parser itself.
            execute_from_command_line(["django-admin", "help", "compilemessages"])

    def test_one_locale_excluded(self):
        call_command("compilemessages", exclude=["it"], verbosity=0)
        self.assertTrue(os.path.exists(self.MO_FILE % "en"))
        self.assertTrue(os.path.exists(self.MO_FILE % "fr"))
        self.assertFalse(os.path.exists(self.MO_FILE % "it"))

    def test_multiple_locales_excluded(self):
        call_command("compilemessages", exclude=["it", "fr"], verbosity=0)
        self.assertTrue(os.path.exists(self.MO_FILE % "en"))
        self.assertFalse(os.path.exists(self.MO_FILE % "fr"))
        self.assertFalse(os.path.exists(self.MO_FILE % "it"))

    def test_one_locale_excluded_with_locale(self):
        call_command(
            "compilemessages", locale=["en", "fr"], exclude=["fr"], verbosity=0
        )
        self.assertTrue(os.path.exists(self.MO_FILE % "en"))
        self.assertFalse(os.path.exists(self.MO_FILE % "fr"))
        self.assertFalse(os.path.exists(self.MO_FILE % "it"))

    def test_multiple_locales_excluded_with_locale(self):
        call_command(
            "compilemessages",
            locale=["en", "fr", "it"],
            exclude=["fr", "it"],
            verbosity=0,
        )
        self.assertTrue(os.path.exists(self.MO_FILE % "en"))
        self.assertFalse(os.path.exists(self.MO_FILE % "fr"))
        self.assertFalse(os.path.exists(self.MO_FILE % "it"))

class IgnoreDirectoryCompilationTests(MessageCompilationTests):
    # Reuse the exclude directory since it contains some locale fixtures.
    work_subdir = "exclude"
    MO_FILE = "%s/%s/LC_MESSAGES/django.mo"
    CACHE_DIR = Path("cache") / "locale"
    NESTED_DIR = Path("outdated") / "v1" / "locale"

    def setUp(self):
        super().setUp()
        copytree("canned_locale", "locale")
        copytree("canned_locale", self.CACHE_DIR)
        copytree("canned_locale", self.NESTED_DIR)

    def assertAllExist(self, dir, langs):
        self.assertTrue(
            all(Path(self.MO_FILE % (dir, lang)).exists() for lang in langs)
        )

    def assertNoneExist(self, dir, langs):
        self.assertTrue(
            all(Path(self.MO_FILE % (dir, lang)).exists() is False for lang in langs)
        )

    def test_one_locale_dir_ignored(self):
        call_command("compilemessages", ignore=["cache"], verbosity=0)
        self.assertAllExist("locale", ["en", "fr", "it"])
        self.assertNoneExist(self.CACHE_DIR, ["en", "fr", "it"])
        self.assertAllExist(self.NESTED_DIR, ["en", "fr", "it"])

    def test_multiple_locale_dirs_ignored(self):
        call_command(
            "compilemessages", ignore=["cache/locale", "outdated"], verbosity=0
        )
        self.assertAllExist("locale", ["en", "fr", "it"])
        self.assertNoneExist(self.CACHE_DIR, ["en", "fr", "it"])
        self.assertNoneExist(self.NESTED_DIR, ["en", "fr", "it"])

    def test_ignores_based_on_pattern(self):
        call_command("compilemessages", ignore=["*/locale"], verbosity=0)
        self.assertAllExist("locale", ["en", "fr", "it"])
        self.assertNoneExist(self.CACHE_DIR, ["en", "fr", "it"])
        self.assertNoneExist(self.NESTED_DIR, ["en", "fr", "it"])

class CompilationErrorHandling(MessageCompilationTests):
    def test_error_reported_by_msgfmt(self):
        # po file contains wrong po formatting.
        with self.assertRaises(CommandError):
            call_command("compilemessages", locale=["ja"], verbosity=0)

    def test_msgfmt_error_including_non_ascii(self):
        # po file contains invalid msgstr content (triggers non-ascii error content).
        # Make sure the output of msgfmt is unaffected by the current locale.
        env = os.environ.copy()
        env.update({"LC_ALL": "C"})
        with mock.patch(
            "django.core.management.utils.run",
            lambda *args, **kwargs: run(*args, env=env, **kwargs),
        ):
            cmd = MakeMessagesCommand()
            if cmd.gettext_version < (0, 18, 3):
                self.skipTest("python-brace-format is a recent gettext addition.")
            stderr = StringIO()
            with self.assertRaisesMessage(
                CommandError, "compilemessages generated one or more errors"
            ):
                call_command(
                    "compilemessages", locale=["ko"], stdout=StringIO(), stderr=stderr
                )
            self.assertIn("' cannot start a field name", stderr.getvalue())

class ProjectAndAppTests(MessageCompilationTests):
    LOCALE = "ru"
    PROJECT_MO_FILE = "locale/%s/LC_MESSAGES/django.mo" % LOCALE
    APP_MO_FILE = "app_with_locale/locale/%s/LC_MESSAGES/django.mo" % LOCALE

class FuzzyTranslationTest(ProjectAndAppTests):
    def setUp(self):
        super().setUp()
        gettext_module._translations = {}  # flush cache or test will be useless

    def test_nofuzzy_compiling(self):
        with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
            call_command("compilemessages", locale=[self.LOCALE], verbosity=0)
            with translation.override(self.LOCALE):
                self.assertEqual(gettext("Lenin"), "Ленин")
                self.assertEqual(gettext("Vodka"), "Vodka")

    def test_fuzzy_compiling(self):
        with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, "locale")]):
            call_command(
                "compilemessages", locale=[self.LOCALE], fuzzy=True, verbosity=0
            )
            with translation.override(self.LOCALE):
                self.assertEqual(gettext("Lenin"), "Ленин")
                self.assertEqual(gettext("Vodka"), "Водка")

class AppCompilationTest(ProjectAndAppTests):
    def test_app_locale_compiled(self):
        call_command("compilemessages", locale=[self.LOCALE], verbosity=0)
        self.assertTrue(os.path.exists(self.PROJECT_MO_FILE))
        self.assertTrue(os.path.exists(self.APP_MO_FILE))

class PathLibLocaleCompilationTests(MessageCompilationTests):
    work_subdir = "exclude"

    def test_locale_paths_pathlib(self):
        with override_settings(LOCALE_PATHS=[Path(self.test_dir) / "canned_locale"]):
            call_command("compilemessages", locale=["fr"], verbosity=0)
            self.assertTrue(os.path.exists("canned_locale/fr/LC_MESSAGES/django.mo"))


text:
require 'spec_helper'

describe "AwesomeNestedSet" do
  before(:all) do
    self.class.fixtures :categories, :departments, :notes, :things, :brokens, :users, :default_scoped_models
  end

  describe "defaults" do
    it "should have left_column_default" do
      expect(Default.acts_as_nested_set_options[:left_column]).to eq('lft')
    end

    it "should have right_column_default" do
      expect(Default.acts_as_nested_set_options[:right_column]).to eq('rgt')
    end

    it "should have parent_column_default" do
      expect(Default.acts_as_nested_set_options[:parent_column]).to eq('parent_id')
    end

    it " should have a primary_column_default" do
      expect(Default.acts_as_nested_set_options[:primary_column]).to eq('id')
    end

    it "should have scope_default" do
      expect(Default.acts_as_nested_set_options[:scope]).to be_nil
    end

    it "should have left_column_name" do
      expect(Default.left_column_name).to eq('lft')
      expect(Default.new.left_column_name).to eq('lft')
      expect(RenamedColumns.left_column_name).to eq('red')
      expect(RenamedColumns.new.left_column_name).to eq('red')
    end

    it "should have right_column_name" do
      expect(Default.right_column_name).to eq('rgt')
      expect(Default.new.right_column_name).to eq('rgt')
      expect(RenamedColumns.right_column_name).to eq('black')
      expect(RenamedColumns.new.right_column_name).to eq('black')
    end

    it "has a depth_column_name" do
      expect(Default.depth_column_name).to eq('depth')
      expect(Default.new.depth_column_name).to eq('depth')
      expect(RenamedColumns.depth_column_name).to eq('pitch')
      expect(RenamedColumns.depth_column_name).to eq('pitch')
    end

    it "should have parent_column_name" do
      expect(Default.parent_column_name).to eq('parent_id')
      expect(Default.new.parent_column_name).to eq('parent_id')
      expect(RenamedColumns.parent_column_name).to eq('mother_id')
      expect(RenamedColumns.new.parent_column_name).to eq('mother_id')
    end

    it "should have primary_column_name" do
      expect(Default.primary_column_name).to eq('id')
      expect(Default.new.primary_column_name).to eq('id')
      expect(User.primary_column_name).to eq('uuid')
      expect(User.new.primary_column_name).to eq('uuid')
    end
  end

  it "creation_with_altered_column_names" do
    expect {
      RenamedColumns.create!()
    }.not_to raise_exception
  end

  it "creation when existing record has nil left column" do
    expect {
      Broken.create!
    }.not_to raise_exception
  end

  describe "quoted column names" do
    it "quoted_left_column_name" do
      quoted = Default.connection.quote_column_name('lft')
      expect(Default.quoted_left_column_name).to eq(quoted)
      expect(Default.new.quoted_left_column_name).to eq(quoted)
    end

    it "quoted_right_column_name" do
      quoted = Default.connection.quote_column_name('rgt')
      expect(Default.quoted_right_column_name).to eq(quoted)
      expect(Default.new.quoted_right_column_name).to eq(quoted)
    end

    it "quoted_depth_column_name" do
      quoted = Default.connection.quote_column_name('depth')
      expect(Default.quoted_depth_column_name).to eq(quoted)
      expect(Default.new.quoted_depth_column_name).to eq(quoted)
    end

    it "quoted_order_column_name" do
      quoted = Default.connection.quote_column_name('lft')
      expect(Default.quoted_order_column_name).to eq(quoted)
      expect(Default.new.quoted_order_column_name).to eq(quoted)
    end
  end

  describe "protected columns" do
    it "left_column_protected_from_assignment" do
      expect {
        Category.new.lft = 1
      }.to raise_exception(ActiveRecord::ActiveRecordError)
    end

    it "right_column_protected_from_assignment" do
      expect {
        Category.new.rgt = 1
      }.to raise_exception(ActiveRecord::ActiveRecordError)
    end

    it "depth_column_protected_from_assignment" do
      expect {
        Category.new.depth = 1
      }.to raise_exception(ActiveRecord::ActiveRecordError)
    end
  end

  describe "scope" do
    it "scoped_appends_id" do
      expect(ScopedCategory.acts_as_nested_set_options[:scope]).to eq(:organization_id)
    end
  end

  describe "hierarchical structure" do
    it "roots_class_method" do
      found_by_us = Category.where(:parent_id => nil).to_a
      found_by_roots = Category.roots.to_a
      expect(found_by_us.length).to eq(found_by_roots.length)
      found_by_us.each do |root|
        expect(found_by_roots).to include(root)
      end
    end

    it "root_class_method" do
      expect(Category.root).to eq(categories(:top_level))
    end

    it "root" do
      expect(categories(:child_3).root).to eq(categories(:top_level))
    end

    it "root when not persisted and parent_column_name value is self" do
      new_category = Category.new
      expect(new_category.root).to eq(new_category)
    end

    it "root when not persisted and parent_column_name value is set" do
      last_category = Category.last
      expect(Category.new(Default.parent_column_name => last_category.id).root).to eq(last_category.root)
    end

    it "root?" do
      expect(categories(:top_level).root?).to be_truthy
      expect(categories(:top_level_2).root?).to be_truthy
    end

    it "leaves_class_method" do
      expect(Category.where("#{Category.right_column_name} - #{Category.left_column_name} = 1").to_a).to eq(Category.leaves.to_a)
      expect(Category.leaves.count).to eq(4)
      expect(Category.leaves).to include(categories(:child_1))
      expect(Category.leaves).to include(categories(:child_2_1))
      expect(Category.leaves).to include(categories(:child_3))
      expect(Category.leaves).to include(categories(:top_level_2))
    end

    it "leaf" do
      expect(categories(:child_1).leaf?).to be_truthy
      expect(categories(:child_2_1).leaf?).to be_truthy
      expect(categories(:child_3).leaf?).to be_truthy
      expect(categories(:top_level_2).leaf?).to be_truthy

      expect(categories(:top_level).leaf?).to be_falsey
      expect(categories(:child_2).leaf?).to be_falsey
      expect(Category.new.leaf?).to be_falsey
    end

    it "parent" do
      expect(categories(:child_2_1).parent).to eq(categories(:child_2))
    end

    it "self_and_ancestors" do
      child = categories(:child_2_1)
      self_and_ancestors = [categories(:top_level), categories(:child_2), child]
      expect(child.self_and_ancestors).to eq(self_and_ancestors)
    end

    it "ancestors" do
      child = categories(:child_2_1)
      ancestors = [categories(:top_level), categories(:child_2)]
      expect(ancestors).to eq(child.ancestors)
    end

    it "self_and_siblings" do
      child = categories(:child_2)
      self_and_siblings = [categories(:child_1), child, categories(:child_3)]
      expect(self_and_siblings).to eq(child.self_and_siblings)
      expect do
        tops = [categories(:top_level), categories(:top_level_2)]
        assert_equal tops, categories(:top_level).self_and_siblings
      end.not_to raise_exception
    end

    it "siblings" do
      child = categories(:child_2)
      siblings = [categories(:child_1), categories(:child_3)]
      expect(siblings).to eq(child.siblings)
    end

    it "leaves" do
      leaves = [categories(:child_1), categories(:child_2_1), categories(:child_3)]
      expect(categories(:top_level).leaves).to eq(leaves)
    end
  end

  describe "level" do
    it "returns the correct level" do
      expect(categories(:top_level).level).to eq(0)
      expect(categories(:child_1).level).to eq(1)
      expect(categories(:child_2_1).level).to eq(2)
    end

    context "given parent associations are loaded" do
      it "returns the correct level" do
        child = categories(:child_1)
        if child.respond_to?(:association)
          child.association(:parent).load_target
          child.parent.association(:parent).load_target
          expect(child.level).to eq(1)
        else
          skip 'associations not used where child#association is not a method'
        end
      end
    end
  end

  describe "depth" do
    context "in general" do
      let(:lawyers) { Category.create!(:name => "lawyers") }
      let(:us) { Category.create!(:name => "United States") }
      let(:new_york) { Category.create!(:name => "New York") }
      let(:patent) { Category.create!(:name => "Patent Law") }
      let(:ch) { Category.create!(:name => "Switzerland") }
      let(:bern) { Category.create!(:name => "Bern") }

      before(:each) do
        # lawyers > us > new_york > patent
        #         > ch > bern
        us.move_to_child_of(lawyers)
        new_york.move_to_child_of(us)
        patent.move_to_child_of(new_york)
        ch.move_to_child_of(lawyers)
        bern.move_to_child_of(ch)
        [lawyers, us, new_york, patent, ch, bern].each(&:reload)
      end

      it "updates depth when moved into child position" do
        expect(lawyers.depth).to eq(0)
        expect(us.depth).to eq(1)
        expect(new_york.depth).to eq(2)
        expect(patent.depth).to eq(3)
        expect(ch.depth).to eq(1)
        expect(bern.depth).to eq(2)
      end

      it "decreases depth of all descendants when parent is moved up" do
        # lawyers
        # us > new_york > patent
        us.move_to_right_of(lawyers)
        [lawyers, us, new_york, patent, ch, bern].each(&:reload)
        expect(us.depth).to eq(0)
        expect(new_york.depth).to eq(1)
        expect(patent.depth).to eq(2)
        expect(ch.depth).to eq(1)
        expect(bern.depth).to eq(2)
      end

      it "keeps depth of all descendants when parent is moved right" do
        us.move_to_right_of(ch)
        [lawyers, us, new_york, patent, ch, bern].each(&:reload)
        expect(us.depth).to eq(1)
        expect(new_york.depth).to eq(2)
        expect(patent.depth).to eq(3)
        expect(ch.depth).to eq(1)
        expect(bern.depth).to eq(2)
      end

      it "increases depth of all descendants when parent is moved down" do
        us.move_to_child_of(bern)
        [lawyers, us, new_york, patent, ch, bern].each(&:reload)
        expect(us.depth).to eq(3)
        expect(new_york.depth).to eq(4)
        expect(patent.depth).to eq(5)
        expect(ch.depth).to eq(1)
        expect(bern.depth).to eq(2)
      end
    end

    it "is magic and does not apply when column is missing" do
      expect { NoDepth.create!(:name => "shallow") }.not_to raise_error
      expect { NoDepth.first.save }.not_to raise_error
      expect { NoDepth.rebuild! }.not_to raise_error

      expect(NoDepth.method_defined?(:depth)).to be_falsey
      expect(NoDepth.first.respond_to?(:depth)).to be_falsey
    end
  end

  it "has_children?" do
    expect(categories(:child_2_1).children.empty?).to be_truthy
    expect(categories(:child_2).children.empty?).to be_falsey
    expect(categories(:top_level).children.empty?).to be_falsey
  end

  it "self_and_descendants" do
    parent = categories(:top_level)
    self_and_descendants = [
      parent,
      categories(:child_1),
      categories(:child_2),
      categories(:child_2_1),
      categories(:child_3)
    ]
    expect(self_and_descendants).to eq(parent.self_and_descendants)
    expect(self_and_descendants.count).to eq(parent.self_and_descendants.count)
  end

  it "descendants" do
    lawyers = Category.create!(:name => "lawyers")
    us = Category.create!(:name => "United States")
    us.move_to_child_of(lawyers)
    patent = Category.create!(:name => "Patent Law")
    patent.move_to_child_of(us)
    lawyers.reload

    expect(lawyers.children.size).to eq(1)
    expect(us.children.size).to eq(1)
    expect(lawyers.descendants.size).to eq(2)
  end

  it "self_and_descendants" do
    parent = categories(:top_level)
    descendants = [
      categories(:child_1),
      categories(:child_2),
      categories(:child_2_1),
      categories(:child_3)
    ]
    expect(descendants).to eq(parent.descendants)
  end

  it "children" do
    category = categories(:top_level)
    category.children.each {|c| expect(category.id).to eq(c.parent_id) }
  end

  it "order_of_children" do
    categories(:child_2).move_left
    expect(categories(:child_2)).to eq(categories(:top_level).children[0])
    expect(categories(:child_1)).to eq(categories(:top_level).children[1])
    expect(categories(:child_3)).to eq(categories(:top_level).children[2])
  end

  it "is_or_is_ancestor_of?" do
    expect(categories(:top_level).is_or_is_ancestor_of?(categories(:child_1))).to be_truthy
    expect(categories(:top_level).is_or_is_ancestor_of?(categories(:child_2_1))).to be_truthy
    expect(categories(:child_2).is_or_is_ancestor_of?(categories(:child_2_1))).to be_truthy
    expect(categories(:child_2_1).is_or_is_ancestor_of?(categories(:child_2))).to be_falsey
    expect(categories(:child_1).is_or_is_ancestor_of?(categories(:child_2))).to be_falsey
    expect(categories(:child_1).is_or_is_ancestor_of?(categories(:child_1))).to be_truthy
  end

  it "is_ancestor_of?" do
    expect(categories(:top_level).is_ancestor_of?(categories(:child_1))).to be_truthy
    expect(categories(:top_level).is_ancestor_of?(categories(:child_2_1))).to be_truthy
    expect(categories(:child_2).is_ancestor_of?(categories(:child_2_1))).to be_truthy
    expect(categories(:child_2_1).is_ancestor_of?(categories(:child_2))).to be_falsey
    expect(categories(:child_1).is_ancestor_of?(categories(:child_2))).to be_falsey
    expect(categories(:child_1).is_ancestor_of?(categories(:child_1))).to be_falsey
  end

  it "is_or_is_ancestor_of_with_scope" do
    root = ScopedCategory.root
    child = root.children.first
    expect(root.is_or_is_ancestor_of?(child)).to be_truthy
    child.update_attribute :organization_id, 999999999
    expect(root.is_or_is_ancestor_of?(child)).to be_falsey
  end

  it "is_or_is_descendant_of?" do
    expect(categories(:child_1).is_or_is_descendant_of?(categories(:top_level))).to be_truthy
    expect(categories(:child_2_1).is_or_is_descendant_of?(categories(:top_level))).to be_truthy
    expect(categories(:child_2_1).is_or_is_descendant_of?(categories(:child_2))).to be_truthy
    expect(categories(:child_2).is_or_is_descendant_of?(categories(:child_2_1))).to be_falsey
    expect(categories(:child_2).is_or_is_descendant_of?(categories(:child_1))).to be_falsey
    expect(categories(:child_1).is_or_is_descendant_of?(categories(:child_1))).to be_truthy
  end

  it "is_descendant_of?" do
    expect(categories(:child_1).is_descendant_of?(categories(:top_level))).to be_truthy
    expect(categories(:child_2_1).is_descendant_of?(categories(:top_level))).to be_truthy
    expect(categories(:child_2_1).is_descendant_of?(categories(:child_2))).to be_truthy
    expect(categories(:child_2).is_descendant_of?(categories(:child_2_1))).to be_falsey
    expect(categories(:child_2).is_descendant_of?(categories(:child_1))).to be_falsey
    expect(categories(:child_1).is_descendant_of?(categories(:child_1))).to be_falsey
  end

  it "is_or_is_descendant_of_with_scope" do
    root = ScopedCategory.root
    child = root.children.first
    expect(child.is_or_is_descendant_of?(root)).to be_truthy
    child.update_attribute :organization_id, 999999999
    expect(child.is_or_is_descendant_of?(root)).to be_falsey
  end

  it "same_scope?" do
    root = ScopedCategory.root
    child = root.children.first
    expect(child.same_scope?(root)).to be_truthy
    child.update_attribute :organization_id, 999999999
    expect(child.same_scope?(root)).to be_falsey
  end

  it "left_sibling" do
    expect(categories(:child_1)).to eq(categories(:child_2).left_sibling)
    expect(categories(:child_2)).to eq(categories(:child_3).left_sibling)
  end

  it "left_sibling_of_root" do
    expect(categories(:top_level).left_sibling).to be_nil
  end

  it "left_sibling_without_siblings" do
    expect(categories(:child_2_1).left_sibling).to be_nil
  end

  it "left_sibling_of_leftmost_node" do
    expect(categories(:child_1).left_sibling).to be_nil
  end

  it "right_sibling" do
    expect(categories(:child_3)).to eq(categories(:child_2).right_sibling)
    expect(categories(:child_2)).to eq(categories(:child_1).right_sibling)
  end

  it "right_sibling_of_root" do
    expect(categories(:top_level_2)).to eq(categories(:top_level).right_sibling)
    expect(categories(:top_level_2).right_sibling).to be_nil
  end

  it "right_sibling_without_siblings" do
    expect(categories(:child_2_1).right_sibling).to be_nil
  end

  it "right_sibling_of_rightmost_node" do
    expect(categories(:child_3).right_sibling).to be_nil
  end

  it "move_left" do
    categories(:child_2).move_left
    expect(categories(:child_2).left_sibling).to be_nil
    expect(categories(:child_1)).to eq(categories(:child_2).right_sibling)
    expect(Category.valid?).to be_truthy
  end

  it "move_right" do
    categories(:child_2).move_right
    expect(categories(:child_2).right_sibling).to be_nil
    expect(categories(:child_3)).to eq(categories(:child_2).left_sibling)
    expect(Category.valid?).to be_truthy
  end

  it "move_to_left_of" do
    categories(:child_3).move_to_left_of(categories(:child_1))
    expect(categories(:child_3).left_sibling).to be_nil
    expect(categories(:child_1)).to eq(categories(:child_3).right_sibling)
    expect(Category.valid?).to be_truthy
  end

  it "move_to_right_of" do
    categories(:child_1).move_to_right_of(categories(:child_3))
    expect(categories(:child_1).right_sibling).to be_nil
    expect(categories(:child_3)).to eq(categories(:child_1).left_sibling)
    expect(Category.valid?).to be_truthy
  end

  it "move_to_root" do
    categories(:child_2).move_to_root
    expect(categories(:child_2).parent).to be_nil
    expect(categories(:child_2).level).to eq(0)
    expect(categories(:child_2_1).level).to eq(1)
    expect(categories(:child_2).left).to eq(9)
    expect(categories(:child_2).right).to eq(12)
    expect(Category.valid?).to be_truthy
  end

  it "move_to_child_of" do
    categories(:child_1).move_to_child_of(categories(:child_3))
    expect(categories(:child_3).id).to eq(categories(:child_1).parent_id)
    expect(Category.valid?).to be_truthy
  end

  describe "#move_to_child_with_index" do
    it "move to a node without child" do
      categories(:child_1).move_to_child_with_index(categories(:child_3), 0)
      expect(categories(:child_3).id).to eq(categories(:child_1).parent_id)
      expect(categories(:child_1).left).to eq(7)
      expect(categories(:child_1).right).to eq(8)
      expect(categories(:child_3).left).to eq(6)
      expect(categories(:child_3).right).to eq(9)
      expect(Category.valid?).to be_truthy
    end

    it "move to a node to the left child" do
      categories(:child_1).move_to_child_with_index(categories(:child_2), 0)
      expect(categories(:child_1).parent_id).to eq(categories(:child_2).id)
      expect(categories(:child_2_1).left).to eq(5)
      expect(categories(:child_2_1).right).to eq(6)
      expect(categories(:child_1).left).to eq(3)
      expect(categories(:child_1).right).to eq(4)
      categories(:child_2).reload
      expect(categories(:child_2).left).to eq(2)
      expect(categories(:child_2).right).to eq(7)
    end

    it "move to a node to the right child" do
      categories(:child_1).move_to_child_with_index(categories(:child_2), 1)
      expect(categories(:child_1).parent_id).to eq(categories(:child_2).id)
      expect(categories(:child_2_1).left).to eq(3)
      expect(categories(:child_2_1).right).to eq(4)
      expect(categories(:child_1).left).to eq(5)
      expect(categories(:child_1).right).to eq(6)
      categories(:child_2).reload
      expect(categories(:child_2).left).to eq(2)
      expect(categories(:child_2).right).to eq(7)
    end

    it "move downward within current parent" do
      categories(:child_1).move_to_child_with_index(categories(:top_level), 1)
      expect(categories(:child_1).parent_id).to eq(categories(:top_level).id)
      expect(categories(:child_1).left).to eq(6)
      expect(categories(:child_1).right).to eq(7)
      categories(:child_2).reload
      expect(categories(:child_2).parent_id).to eq(categories(:top_level).id)
      expect(categories(:child_2).left).to eq(2)
      expect(categories(:child_2).right).to eq(5)
    end

    it "move to the same position within current parent" do
      categories(:child_1).move_to_child_with_index(categories(:top_level), 0)
      expect(categories(:child_1).parent_id).to eq(categories(:top_level).id)
      expect(categories(:child_1).left).to eq(2)
      expect(categories(:child_1).right).to eq(3)
    end
  end

  it "move_to_child_of_appends_to_end" do
    child = Category.create! :name => 'New Child'
    child.move_to_child_of categories(:top_level)
    expect(child).to eq(categories(:top_level).children.last)
  end

  it "subtree_move_to_child_of" do
    expect(categories(:child_2).left).to eq(4)
    expect(categories(:child_2).right).to eq(7)

    expect(categories(:child_1).left).to eq(2)
    expect(categories(:child_1).right).to eq(3)

    categories(:child_2).move_to_child_of(categories(:child_1))
    expect(Category.valid?).to be_truthy
    expect(categories(:child_1).id).to eq(categories(:child_2).parent_id)

    expect(categories(:child_2).left).to eq(3)
    expect(categories(:child_2).right).to eq(6)
    expect(categories(:child_1).left).to eq(2)
    expect(categories(:child_1).right).to eq(7)
  end

  it "slightly_difficult_move_to_child_of" do
    expect(categories(:top_level_2).left).to eq(11)
    expect(categories(:top_level_2).right).to eq(12)

    # create a new top-level node and move single-node top-level tree inside it.
    new_top = Category.create(:name => 'New Top')
    expect(new_top.left).to eq(13)
    expect(new_top.right).to eq(14)

    categories(:top_level_2).move_to_child_of(new_top)

    expect(Category.valid?).to be_truthy
    expect(new_top.id).to eq(categories(:top_level_2).parent_id)

    expect(categories(:top_level_2).left).to eq(12)
    expect(categories(:top_level_2).right).to eq(13)
    expect(new_top.left).to eq(11)
    expect(new_top.right).to eq(14)
  end

  it "difficult_move_to_child_of" do
    expect(categories(:top_level).left).to eq(1)
    expect(categories(:top_level).right).to eq(10)
    expect(categories(:child_2_1).left).to eq(5)
    expect(categories(:child_2_1).right).to eq(6)

    # create a new top-level node and move an entire top-level tree inside it.
    new_top = Category.create(:name => 'New Top')
    categories(:top_level).move_to_child_of(new_top)
    categories(:child_2_1).reload
    expect(Category.valid?).to be_truthy
    expect(new_top.id).to eq(categories(:top_level).parent_id)

    expect(categories(:top_level).left).to eq(4)
    expect(categories(:top_level).right).to eq(13)
    expect(categories(:child_2_1).left).to eq(8)
    expect(categories(:child_2_1).right).to eq(9)
  end

  #rebuild swaps the position of the 2 children when added using move_to_child twice onto same parent
  it "move_to_child_more_than_once_per_parent_rebuild" do
    root1 = Category.create(:name => 'Root1')
    root2 = Category.create(:name => 'Root2')
    root3 = Category.create(:name => 'Root3')

    root2.move_to_child_of root1
    root3.move_to_child_of root1

    output = Category.roots.last.to_text
    Category.update_all('lft = null, rgt = null')
    Category.rebuild!

    expect(Category.roots.last.to_text).to eq(output)
  end

  # doing move_to_child twice onto same parent from the furthest right first
  it "move_to_child_more_than_once_per_parent_outside_in" do
    node1 = Category.create(:name => 'Node-1')
    node2 = Category.create(:name => 'Node-2')
    node3 = Category.create(:name => 'Node-3')

    node2.move_to_child_of node1
    node3.move_to_child_of node1

    output = Category.roots.last.to_text
    Category.update_all('lft = null, rgt = null')
    Category.rebuild!

    expect(Category.roots.last.to_text).to eq(output)
  end

  it "should_move_to_ordered_child" do
    node1 = Category.create(:name => 'Node-1')
    node2 = Category.create(:name => 'Node-2')
    node3 = Category.create(:name => 'Node-3')

    node2.move_to_ordered_child_of(node1, "name")

    assert_equal node1, node2.parent
    assert_equal 1, node1.children.count

    node3.move_to_ordered_child_of(node1, "name", true) # acending

    assert_equal node1, node3.parent
    assert_equal 2, node1.children.count
    assert_equal node2.name, node1.children[0].name
    assert_equal node3.name, node1.children[1].name

    node3.move_to_ordered_child_of(node1, "name", false) # decending
    node1.reload

    expect(node3.parent).to eq(node1)
    expect(node1.children.count).to be(2)
    expect(node1.children[0].name).to eq(node3.name)
    expect(node1.children[1].name).to eq(node2.name)
  end

  it "should be able to rebuild without validating each record" do
    root1 = Category.create(:name => 'Root1')
    root2 = Category.create(:name => 'Root2')
    root3 = Category.create(:name => 'Root3')

    root2.move_to_child_of root1
    root3.move_to_child_of root1

    root2.name = nil
    root2.save!(:validate => false)

    output = Category.roots.last.to_text
    Category.update_all('lft = null, rgt = null')
    Category.rebuild!(false)

    expect(Category.roots.last.to_text).to eq(output)
  end

  it "valid_with_null_lefts" do
    expect(Category.valid?).to be_truthy
    Category.update_all('lft = null')
    expect(Category.valid?).to be_falsey
  end

  it "valid_with_null_rights" do
    expect(Category.valid?).to be_truthy
    Category.update_all('rgt = null')
    expect(Category.valid?).to be_falsey
  end

  it "valid_with_missing_intermediate_node" do
    # Even though child_2_1 will still exist, it is a sign of a sloppy delete, not an invalid tree.
    expect(Category.valid?).to be_truthy
    Category.delete(categories(:child_2).id)
    expect(Category.valid?).to be_truthy
  end

  it "valid_with_overlapping_and_rights" do
    expect(Category.valid?).to be_truthy
    categories(:top_level_2)['lft'] = 0
    categories(:top_level_2).save
    expect(Category.valid?).to be_falsey
  end

  it "rebuild" do
    expect(Category.valid?).to be_truthy
    before_text = Category.root.to_text
    Category.update_all('lft = null, rgt = null')
    Category.rebuild!
    expect(Category.valid?).to be_truthy
    expect(before_text).to eq(Category.root.to_text)
  end

  it "move_possible_for_sibling" do
    expect(categories(:child_2).move_possible?(categories(:child_1))).to be_truthy
  end

  it "move_not_possible_to_self" do
    expect(categories(:top_level).move_possible?(categories(:top_level))).to be_falsey
  end

  it "move_not_possible_to_parent" do
    categories(:top_level).descendants.each do |descendant|
      expect(categories(:top_level).move_possible?(descendant)).to be_falsey
      expect(descendant.move_possible?(categories(:top_level))).to be_truthy
    end
  end

  it "is_or_is_ancestor_of?" do
    [:child_1, :child_2, :child_2_1, :child_3].each do |c|
      expect(categories(:top_level).is_or_is_ancestor_of?(categories(c))).to be_truthy
    end
    expect(categories(:top_level).is_or_is_ancestor_of?(categories(:top_level_2))).to be_falsey
  end

  it "left_and_rights_valid_with_blank_left" do
    expect(Category.left_and_rights_valid?).to be_truthy
    categories(:child_2)[:lft] = nil
    categories(:child_2).save(:validate => false)
    expect(Category.left_and_rights_valid?).to be_falsey
  end

  it "left_and_rights_valid_with_blank_right" do
    expect(Category.left_and_rights_valid?).to be_truthy
    categories(:child_2)[:rgt] = nil
    categories(:child_2).save(:validate => false)
    expect(Category.left_and_rights_valid?).to be_falsey
  end

  it "left_and_rights_valid_with_equal" do
    expect(Category.left_and_rights_valid?).to be_truthy
    categories(:top_level_2)[:lft] = categories(:top_level_2)[:rgt]
    categories(:top_level_2).save(:validate => false)
    expect(Category.left_and_rights_valid?).to be_falsey
  end

  it "left_and_rights_valid_with_left_equal_to_parent" do
    expect(Category.left_and_rights_valid?).to be_truthy
    categories(:child_2)[:lft] = categories(:top_level)[:lft]
    categories(:child_2).save(:validate => false)
    expect(Category.left_and_rights_valid?).to be_falsey
  end

  it "left_and_rights_valid_with_right_equal_to_parent" do
    expect(Category.left_and_rights_valid?).to be_truthy
    categories(:child_2)[:rgt] = categories(:top_level)[:rgt]
    categories(:child_2).save(:validate => false)
    expect(Category.left_and_rights_valid?).to be_falsey
  end

  it "moving_dirty_objects_doesnt_invalidate_tree" do
    r1 = Category.create :name => "Test 1"
    r2 = Category.create :name => "Test 2"
    r3 = Category.create :name => "Test 3"
    r4 = Category.create :name => "Test 4"
    nodes = [r1, r2, r3, r4]

    r2.move_to_child_of(r1)
    expect(Category.valid?).to be_truthy

    r3.move_to_child_of(r1)
    expect(Category.valid?).to be_truthy

    r4.move_to_child_of(r2)
    expect(Category.valid?).to be_truthy
  end

  it "multi_scoped_no_duplicates_for_columns?" do
    expect {
      Note.no_duplicates_for_columns?
    }.not_to raise_exception
  end

  it "multi_scoped_all_roots_valid?" do
    expect {
      Note.all_roots_valid?
    }.not_to raise_exception
  end

  it "multi_scoped" do
    note1 = Note.create!(:body => "A", :notable_id => 2, :notable_type => 'Category')
    note2 = Note.create!(:body => "B", :notable_id => 2, :notable_type => 'Category')
    note3 = Note.create!(:body => "C", :notable_id => 2, :notable_type => 'Default')

    expect([note1, note2]).to eq(note1.self_and_siblings)
    expect([note3]).to eq(note3.self_and_siblings)
  end

  it "multi_scoped_rebuild" do
    root = Note.create!(:body => "A", :notable_id => 3, :notable_type => 'Category')
    child1 = Note.create!(:body => "B", :notable_id => 3, :notable_type => 'Category')
    child2 = Note.create!(:body => "C", :notable_id => 3, :notable_type => 'Category')

    child1.move_to_child_of root
    child2.move_to_child_of root

    Note.update_all('lft = null, rgt = null')
    Note.rebuild!

    expect(Note.roots.find_by_body('A')).to eq(root)
    expect([child1, child2]).to eq(Note.roots.find_by_body('A').children)
  end

  it "same_scope_with_multi_scopes" do
    expect {
      notes(:scope1).same_scope?(notes(:child_1))
    }.not_to raise_exception
    expect(notes(:scope1).same_scope?(notes(:child_1))).to be_truthy
    expect(notes(:child_1).same_scope?(notes(:scope1))).to be_truthy
    expect(notes(:scope1).same_scope?(notes(:scope2))).to be_falsey
  end

  it "quoting_of_multi_scope_column_names" do
    ## Proper Array Assignment for different DBs as per their quoting column behavior
    if Note.connection.adapter_name.match(/oracle/i)
      expected_quoted_scope_column_names = ["\"NOTABLE_ID\"", "\"NOTABLE_TYPE\""]
    elsif Note.connection.adapter_name.match(/mysql/i)
      expected_quoted_scope_column_names = ["`notable_id`", "`notable_type`"]
    else
      expected_quoted_scope_column_names = ["\"notable_id\"", "\"notable_type\""]
    end
    expect(Note.quoted_scope_column_names).to eq(expected_quoted_scope_column_names)
  end

  it "equal_in_same_scope" do
    expect(notes(:scope1)).to eq(notes(:scope1))
    expect(notes(:scope1)).not_to eq(notes(:child_1))
  end

  it "equal_in_different_scopes" do
    expect(notes(:scope1)).not_to eq(notes(:scope2))
  end

  it "delete_does_not_invalidate" do
    Category.acts_as_nested_set_options[:dependent] = :delete
    categories(:child_2).destroy
    expect(Category.valid?).to be_truthy
  end

  it "destroy_does_not_invalidate" do
    Category.acts_as_nested_set_options[:dependent] = :destroy
    categories(:child_2).destroy
    expect(Category.valid?).to be_truthy
  end

  it "destroy_multiple_times_does_not_invalidate" do
    Category.acts_as_nested_set_options[:dependent] = :destroy
    categories(:child_2).destroy
    categories(:child_2).destroy
    expect(Category.valid?).to be_truthy
  end

  it "assigning_parent_id_on_create" do
    category = Category.create!(:name => "Child", :parent_id => categories(:child_2).id)
    expect(categories(:child_2)).to eq(category.parent)
    expect(categories(:child_2).id).to eq(category.parent_id)
    expect(category.left).not_to be_nil
    expect(category.right).not_to be_nil
    expect(Category.valid?).to be_truthy
  end

  it "assigning_parent_on_create" do
    category = Category.create!(:name => "Child", :parent => categories(:child_2))
    expect(categories(:child_2)).to eq(category.parent)
    expect(categories(:child_2).id).to eq(category.parent_id)
    expect(category.left).not_to be_nil
    expect(category.right).not_to be_nil
    expect(Category.valid?).to be_truthy
  end

  it "assigning_parent_id_to_nil_on_create" do
    category = Category.create!(:name => "New Root", :parent_id => nil)
    expect(category.parent).to be_nil
    expect(category.parent_id).to be_nil
    expect(category.left).not_to be_nil
    expect(category.right).not_to be_nil
    expect(Category.valid?).to be_truthy
  end

  it "assigning_parent_id_on_update" do
    category = categories(:child_2_1)
    category.parent_id = categories(:child_3).id
    category.save
    category.reload
    categories(:child_3).reload
    expect(categories(:child_3)).to eq(category.parent)
    expect(categories(:child_3).id).to eq(category.parent_id)
    expect(Category.valid?).to be_truthy
  end

  it "assigning_parent_on_update" do
    category = categories(:child_2_1)
    category.parent = categories(:child_3)
    category.save
    category.reload
    categories(:child_3).reload
    expect(categories(:child_3)).to eq(category.parent)
    expect(categories(:child_3).id).to eq(category.parent_id)
    expect(Category.valid?).to be_truthy
  end

  it "assigning_parent_id_to_nil_on_update" do
    category = categories(:child_2_1)
    category.parent_id = nil
    category.save
    expect(category.parent).to be_nil
    expect(category.parent_id).to be_nil
    expect(Category.valid?).to be_truthy
  end

  it "creating_child_from_parent" do
    category = categories(:child_2).children.create!(:name => "Child")
    expect(categories(:child_2)).to eq(category.parent)
    expect(categories(:child_2).id).to eq(category.parent_id)
    expect(category.left).not_to be_nil
    expect(category.right).not_to be_nil
    expect(Category.valid?).to be_truthy
  end

  def check_structure(entries, structure)
    structure = structure.dup
    Category.each_with_level(entries) do |category, level|
      expected_level, expected_name = structure.shift
      expect(expected_name).to eq(category.name)
      expect(expected_level).to eq(level)
    end
  end

  it "each_with_level" do
    levels = [
      [0, "Top Level"],
      [1, "Child 1"],
      [1, "Child 2"],
      [2, "Child 2.1"],
      [1, "Child 3" ]
    ]

    check_structure(Category.root.self_and_descendants, levels)

    # test some deeper structures
    category = Category.find_by_name("Child 1")
    c1 = Category.new(:name => "Child 1.1")
    c2 = Category.new(:name => "Child 1.1.1")
    c3 = Category.new(:name => "Child 1.1.1.1")
    c4 = Category.new(:name => "Child 1.2")
    [c1, c2, c3, c4].each(&:save!)

    c1.move_to_child_of(category)
    c2.move_to_child_of(c1)
    c3.move_to_child_of(c2)
    c4.move_to_child_of(category)

    levels = [
      [0, "Top Level"],
      [1, "Child 1"],
      [2, "Child 1.1"],
      [3, "Child 1.1.1"],
      [4, "Child 1.1.1.1"],
      [2, "Child 1.2"],
      [1, "Child 2"],
      [2, "Child 2.1"],
      [1, "Child 3" ]
    ]

    check_structure(Category.root.self_and_descendants, levels)
  end

  describe "before_move_callback" do
    it "should fire the callback" do
      expect(categories(:child_2)).to receive(:custom_before_move)
      categories(:child_2).move_to_root
    end

    it "should stop move when callback returns false" do
      Category.test_allows_move = false
      expect(categories(:child_3).move_to_root).to be_falsey
      expect(categories(:child_3).root?).to be_falsey
    end

    it "should not halt save actions" do
      Category.test_allows_move = false
      categories(:child_3).parent_id = nil
      expect(categories(:child_3).save).to be_truthy
    end
  end

  describe "counter_cache" do

    it "should allow use of a counter cache for children" do
      note1 = things(:parent1)
      expect(note1.children.count).to eq(2)
    end

    it "should increment the counter cache on create" do
      note1 = things(:parent1)
      expect(note1.children.count).to eq(2)
      expect(note1[:children_count]).to eq(2)
      note1.children.create :body => 'Child 3'
      expect(note1.children.count).to eq(3)
      note1.reload
      expect(note1[:children_count]).to eq(3)
    end

    it "should decrement the counter cache on destroy" do
      note1 = things(:parent1)
      expect(note1.children.count).to eq(2)
      expect(note1[:children_count]).to eq(2)
      note1.children.last.destroy
      expect(note1.children.count).to eq(1)
      note1.reload
      expect(note1[:children_count]).to eq(1)
    end
  end

  describe "association callbacks on children" do
    it "should call the appropriate callbacks on the children :has_many association " do
      root = DefaultWithCallbacks.create
      expect(root).not_to be_new_record

      child = root.children.build

      expect(root.before_add).to eq(child)
      expect(root.after_add).to  eq(child)

      expect(root.before_remove).not_to eq(child)
      expect(root.after_remove).not_to  eq(child)

      expect(child.save).to be_truthy
      expect(root.children.delete(child)).to be_truthy

      expect(root.before_remove).to eq(child)
      expect(root.after_remove).to  eq(child)
    end
  end

  describe 'rebuilding tree with a default scope ordering' do
    it "doesn't throw exception" do
      expect { Position.rebuild! }.not_to raise_error
    end
  end

  describe 'creating roots with a default scope ordering' do
    it "assigns rgt and lft correctly" do
      alpha = Order.create(:name => 'Alpha')
      gamma = Order.create(:name => 'Gamma')
      omega = Order.create(:name => 'Omega')

      expect(alpha.lft).to eq(1)
      expect(alpha.rgt).to eq(2)
      expect(gamma.lft).to eq(3)
      expect(gamma.rgt).to eq(4)
      expect(omega.lft).to eq(5)
      expect(omega.rgt).to eq(6)
    end
  end

  describe 'moving node from one scoped tree to another' do
    xit "moves single node correctly" do
      root1 = Note.create!(:body => "A-1", :notable_id => 4, :notable_type => 'Category')
      child1_1 = Note.create!(:body => "B-1", :notable_id => 4, :notable_type => 'Category')
      child1_2 = Note.create!(:body => "C-1", :notable_id => 4, :notable_type => 'Category')
      child1_1.move_to_child_of root1
      child1_2.move_to_child_of root1

      root2 = Note.create!(:body => "A-2", :notable_id => 5, :notable_type => 'Category')
      child2_1 = Note.create!(:body => "B-2", :notable_id => 5, :notable_type => 'Category')
      child2_2 = Note.create!(:body => "C-2", :notable_id => 5, :notable_type => 'Category')
      child2_1.move_to_child_of root2
      child2_2.move_to_child_of root2

      child1_1.update_attributes!(:notable_id => 5)
      child1_1.move_to_child_of root2

      expect(root1.children).to eq([child1_2])
      expect(root2.children).to eq([child2_1, child2_2, child1_1])

      expect(Note.valid?).to eq(true)
    end

    xit "moves node with children correctly" do
      root1 = Note.create!(:body => "A-1", :notable_id => 4, :notable_type => 'Category')
      child1_1 = Note.create!(:body => "B-1", :notable_id => 4, :notable_type => 'Category')
      child1_2 = Note.create!(:body => "C-1", :notable_id => 4, :notable_type => 'Category')
      child1_1.move_to_child_of root1
      child1_2.move_to_child_of child1_1

      root2 = Note.create!(:body => "A-2", :notable_id => 5, :notable_type => 'Category')
      child2_1 = Note.create!(:body => "B-2", :notable_id => 5, :notable_type => 'Category')
      child2_2 = Note.create!(:body => "C-2", :notable_id => 5, :notable_type => 'Category')
      child2_1.move_to_child_of root2
      child2_2.move_to_child_of root2

      child1_1.update_attributes!(:notable_id => 5)
      child1_1.move_to_child_of root2

      expect(root1.children).to eq([])
      expect(root2.children).to eq([child2_1, child2_2, child1_1])
      child1_1.children is_expected.to eq([child1_2])
      expect(root2.siblings).to eq([child2_1, child2_2, child1_1, child1_2])

      expect(Note.valid?).to eq(true)
    end
  end

  describe 'specifying custom sort column' do
    it "should sort by the default sort column" do
      expect(Category.order_column).to eq('lft')
    end

    it "should sort by custom sort column" do
      expect(OrderedCategory.acts_as_nested_set_options[:order_column]).to eq('name')
      expect(OrderedCategory.order_column).to eq('name')
    end
  end

  describe 'associate_parents' do
    it 'assigns parent' do
      root = Category.root
      categories = root.self_and_descendants
      categories = Category.associate_parents categories
      expect(categories[1].parent).to be categories.first
    end

    it 'adds children on inverse of association' do
      root = Category.root
      categories = root.self_and_descendants
      categories = Category.associate_parents categories
      expect(categories[0].children.first).to be categories[1]
    end
  end

  describe 'table inheritance' do
    it 'allows creation of a subclass pointing to a superclass' do
      subclass1 = Subclass1.create(name: "Subclass1")
      Subclass2.create(name: "Subclass2", parent_id: subclass1.id)
    end
  end

  describe 'option dependent' do
    it 'destroy should destroy children and node' do
      Category.acts_as_nested_set_options[:dependent] = :destroy
      root = Category.root
      root.destroy!
      expect(Category.where(id: root.id)).to be_empty
      expect(Category.where(parent_id: root.id)).to be_empty
    end

    it "properly destroy association's objects and its children and nodes" do
      Category.acts_as_nested_set_options[:dependent] = :destroy
      user = User.first
      note_ids = user.note_ids
      user.notes.destroy_all
      expect(Note.where(id: note_ids, user_id: user.id).count).to be_zero
    end

    it 'delete should delete children and node' do
      Category.acts_as_nested_set_options[:dependent] = :delete
      root = Category.root
      root.destroy!
      expect(Category.where(id: root.id)).to be_empty
      expect(Category.where(parent_id: root.id)).to be_empty
    end

    describe 'restrict_with_exception' do
      it 'raises an exception' do
        Category.acts_as_nested_set_options[:dependent] = :restrict_with_exception
        root = Category.root
        expect { root.destroy! }.to raise_error  ActiveRecord::DeleteRestrictionError, 'Cannot delete record because of dependent children'
      end

      it 'deletes the leaf' do
        Category.acts_as_nested_set_options[:dependent] = :restrict_with_exception
        leaf = Category.last
        expect(leaf.destroy).to eq(leaf)
      end
    end

    describe 'restrict_with_error' do
      it 'adds the error to the parent' do
        Category.acts_as_nested_set_options[:dependent] = :restrict_with_error
        root = Category.root
        root.destroy
        expect(root.errors[:base]).to eq(["Cannot delete record because dependent children exist"])
      end

      it 'deletes the leaf' do
        Category.acts_as_nested_set_options[:dependent] = :restrict_with_error
        leaf = Category.last
        expect(leaf.destroy).to eq(leaf)
      end
    end
    describe "model with default_scope" do
      it "should have correct #lft & #rgt" do
        parent = DefaultScopedModel.find(6)

        DefaultScopedModel.send(:default_scope, Proc.new { parent.reload.self_and_descendants })

        children = parent.children.create(name: 'Helloworld')

        DefaultScopedModel.unscoped do
          expect(children.is_descendant_of?(parent.reload)).to be true
        end
      end
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
/*
**         $$===================================================$$
**         ||                                                   ||
**         ||          ,;,                ___     _ _           ||
**         ||         +($)+              / __|___| | |___       ||
**         ||         +($)+             | (__/ -_) | / _ \      ||
**         ||          |||           lib \___\___|_|_\___/      ||
**         ||          |||                                      ||
**         ||          |||    /#           High Level           ||
**         ||         _|||_  /'         Programming in C        ||
**         ||       .' ||| '/                                   ||
**         ||      /   ||| / \        http://libcello.org/      ||
**         ||      |   |||/  |                                  ||
**         ||      )_  ||/  _(         Licensed under BSD       ||
**         ||       _) |/| (_                                   ||
**         ||      )   /||   (                                  ||
**         ||     /  }/+++ {  \                                 ||
**         ||    |  {/ |||  }  |                                ||
**         ||    |  /  ~~~     |                                ||
**         ||     \/   \ /    /                                 ||
**         ||     /`-.__Y__.-`                                  ||
**         ||    '-     |              Daniel Holden            ||
**         ||           |                                       ||
**         ||           !      contact@theorangeduck.com        ||
**         ||                                                   ||
**         ||       https://github.com/orangeduck/libCello      ||
**         ||                                                   ||
**         $$===================================================$$
*/

#ifndef CELLO_H
#define CELLO_H

/* Settings */

#ifdef  CELLO_NDEBUG
#define CELLO_BOUND_CHECK  0
#define CELLO_MAGIC_CHECK  0
#define CELLO_ALLOC_CHECK  0
#define CELLO_NULL_CHECK   0
#define CELLO_METHOD_CHECK 0
#define CELLO_MEMORY_CHECK 0
#else
#define CELLO_BOUND_CHECK  1
#define CELLO_MAGIC_CHECK  1
#define CELLO_ALLOC_CHECK  1
#define CELLO_NULL_CHECK   1
#define CELLO_METHOD_CHECK 1
#define CELLO_MEMORY_CHECK 1
#endif

#if CELLO_ALLOC_CHECK == 1
#define CELLO_ALLOC_HEADER (var)AllocStatic,
#else
#define CELLO_ALLOC_HEADER
#endif

#if CELLO_MAGIC_CHECK == 1
#define CELLO_MAGIC_NUM 0xCe110
#define CELLO_MAGIC_HEADER ((var)CELLO_MAGIC_NUM),
#else
#define CELLO_MAGIC_HEADER
#endif

#ifndef CELLO_CACHE
#define CELLO_CACHE 1
#define CELLO_CACHE_HEADER \
  NULL, NULL, NULL, NULL, NULL, NULL, \
  NULL, NULL, NULL, NULL, NULL, NULL, \
  NULL, NULL, NULL, NULL, NULL, NULL,
#define CELLO_CACHE_NUM 18
#else
#define CELLO_CACHE 0
#define CELLO_CACHE_HEADER
#define CELLO_CACHE_NUM 0
#endif

#ifdef _WIN32
#define CELLO_WINDOWS
#endif

#ifdef __unix__
#define CELLO_UNIX
#define CELLO_LINUX
#endif

#ifdef __APPLE__
#define CELLO_UNIX
#define CELLO_MAC
#endif

#ifdef _MSC_VER
#define CELLO_MSC
#define popen _popen
#define pclose _pclose
#define __func__ __FUNCTION__
#ifndef CELLO_NSTRACE
#pragma comment(lib, "DbgHelp.lib")
#endif
#endif

/* Includes */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
#include <setjmp.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <time.h>

#ifdef CELLO_WINDOWS
#include <windows.h>
#ifndef CELLO_NSTRACE
#include <DbgHelp.h>
#endif
#endif

#ifdef CELLO_UNIX
#include <pthread.h>
#ifndef CELLO_NSTRACE
#include <execinfo.h>
#endif
#endif

/* Syntax */

typedef void* var;

#define is ==
#define isnt !=
#define not !
#define and &&
#define or ||
#define in ,

/* Declaration */

#define Cello(T, ...) CelloStruct(T, ##__VA_ARGS__)
#define CelloStruct(T, ...) CelloObject(T, sizeof(struct T), ##__VA_ARGS__)
#define CelloEmpty(T, ...) CelloObject(T, 0, ##__VA_ARGS__)
#define CelloObject(T, S, ...) (var)((char*)((var[]){ NULL, \
  CELLO_ALLOC_HEADER       \
  CELLO_MAGIC_HEADER       \
  CELLO_CACHE_HEADER       \
  NULL, "__Name",     #T,  \
  NULL, "__Size", (var)S,  \
  ##__VA_ARGS__,           \
  NULL, NULL, NULL}) +     \
  sizeof(struct Header))

#define Instance(I, ...) NULL, #I, &((struct I){__VA_ARGS__})

/* Types */

extern var Type;
extern var Tuple;

extern var Ref;
extern var Box;
extern var Int;
extern var Float;
extern var String;

extern var Tree;
extern var List;
extern var Array;
extern var Table;
extern var Range;
extern var Slice;
extern var Zip;
extern var Filter;
extern var Map;
extern var Terminal;
extern var _;

extern var File;
extern var Mutex;
extern var Thread;
extern var Process;
extern var Function;

extern var Exception;
extern var IOError;
extern var KeyError;
extern var BusyError;
extern var TypeError;
extern var ValueError;
extern var ClassError;
extern var FormatError;
extern var ResourceError;
extern var OutOfMemoryError;
extern var IndexOutOfBoundsError;
extern var SegmentationError;
extern var ProgramAbortedError;
extern var DivisionByZeroError;
extern var IllegalInstructionError;
extern var ProgramInterruptedError;
extern var ProgramTerminationError;

/* Data */

enum {
  AllocStatic = 0x01, AllocStack = 0x02,
  AllocHeap   = 0x03, AllocData  = 0x04
};

struct Header {
  var type;
#if CELLO_ALLOC_CHECK == 1
  var alloc;
#endif
#if CELLO_MAGIC_CHECK == 1
  var magic;
#endif
};

struct Type {
  var cls;
  var name;
  var inst;
};

struct Ref {
  var val;
};

struct Box {
  var val;
};

struct Int {
  int64_t val;
};

struct Float {
  double val;
};

struct String {
  char* val;
};

struct Tuple {
  var* items;
};

struct Range {
  var value;
  int64_t start;
  int64_t stop;
  int64_t step;
};

struct Slice {
  var iter;
  var range;
};

struct Zip {
  var iters;
  var values;
};

struct Filter {
  var iter;
  var func;
};

struct Map {
  var iter;
  var curr;
  var func;
};

struct File {
  FILE* file;
};

struct Process {
  FILE* proc;
};

struct Function {
  var (*func)(var);
};

/* Classes */

extern var Doc;
extern var Help;
extern var Cast;
extern var Size;
extern var Alloc;
extern var New;
extern var Copy;
extern var Assign;
extern var Swap;
extern var Cmp;
extern var Hash;
extern var Len;
extern var Iter;
extern var Push;
extern var Concat;
extern var Get;
extern var Sort;
extern var Resize;
extern var C_Str;
extern var C_Int;
extern var C_Float;
extern var Stream;
extern var Pointer;
extern var Call;
extern var Format;
extern var Show;
extern var Current;
extern var Start;
extern var Lock;
extern var Mark;

/* Signatures */

struct Example {
  const char* name;
  const char* body;
};

struct Method {
  const char* name;
  const char* definition;
  const char* description;
};

struct Doc {
  const char* (*name)(void);
  const char* (*brief)(void);
  const char* (*description)(void);
  const char* (*definition)(void);
  struct Example* (*examples)(void);
  struct Method* (*methods)(void);
};

struct Help {
  int (*help_to)(var, var, int);
};

struct Cast {
  var (*cast)(var, var);
};

struct Size {
  size_t (*size)(void);
};

struct Alloc {
  var (*alloc)(void);
  void (*dealloc)(var);
};

struct New {
  void (*construct_with)(var, var);
  void (*destruct)(var);
};

struct Copy {
  var (*copy)(var);
};

struct Assign {
  void (*assign)(var, var);
};

struct Swap {
  void (*swap)(var, var);
};

struct Cmp {
  int (*cmp)(var, var);
};

struct Hash {
  uint64_t (*hash)(var);
};

struct Len {
  size_t (*len)(var);
};

struct Push {
  void (*push)(var, var);
  void (*pop)(var);
  void (*push_at)(var, var, var);
  void (*pop_at)(var, var);
};

struct Concat {
  void (*concat)(var, var);
  void (*append)(var, var);
};

struct Get {
  var  (*get)(var, var);
  void (*set)(var, var, var);
  bool (*mem)(var, var);
  void (*rem)(var, var);
  var (*key_type)(var);
  var (*val_type)(var);
};

struct Iter {
  var (*iter_init)(var);
  var (*iter_next)(var, var);
  var (*iter_last)(var);
  var (*iter_prev)(var, var);
  var (*iter_type)(var);
};

struct Sort {
  void (*sort_by)(var,bool(*f)(var,var));
};

struct Resize {
  void (*resize)(var, size_t);
};

struct C_Str {
  char* (*c_str)(var);
};

struct C_Int {
  int64_t (*c_int)(var);
};

struct C_Float {
  double (*c_float)(var);
};

struct Stream {
  var  (*sopen)(var,var,var);
  void (*sclose)(var);
  void (*sseek)(var,int64_t,int);
  int64_t (*stell)(var);
  void (*sflush)(var);
  bool (*seof)(var);
  size_t (*sread)(var,void*,size_t);
  size_t (*swrite)(var,void*,size_t);
};

struct Pointer {
  void (*ref)(var, var);
  var (*deref)(var);
};

struct Call {
  var (*call_with)(var, var);
};

struct Format {
  int (*format_to)(var,int,const char*,va_list);
  int (*format_from)(var,int,const char*,va_list);
};

struct Show {
  int (*show)(var, var, int);
  int (*look)(var, var, int);
};

struct Current {
  var (*current)(void);
};

struct Start {
  void (*start)(var);
  void (*stop)(var);
  void (*join)(var);
  bool (*running)(var);
};

struct Lock {
  void (*lock)(var);
  void (*unlock)(var);
  bool (*lock_try)(var);
};

struct Mark {
  void (*mark)(var, var, void(*)(var,void*));
};

/* Functions */

const char* name(var type);
const char* brief(var type);
const char* description(var type);
const char* definition(var type);

void help(var self);
int help_to(var out, int pos, var self);

var type_of(var self);
var cast(var self, var type);
var instance(var self, var cls);
bool implements(var self, var cls);
var type_instance(var type, var cls);
bool type_implements(var type, var cls);

#define method(X, C, M, ...) \
  ((struct C*)method_at_offset(X, C, \
  offsetof(struct C, M), #M))->M(X, ##__VA_ARGS__)

#define implements_method(X, C, M) \
  implements_method_at_offset(X, C, offsetof(struct C, M))

#define type_method(T, C, M, ...) \
  ((struct C*)type_method_at_offset(T, C, \
  offsetof(struct C, M), #M))->M(__VA_ARGS__)

#define type_implements_method(T, C, M) \
  type_implements_method_at_offset(T, C, offsetof(struct C, M))

var method_at_offset(var self, var cls, size_t offset, const char* method);
bool implements_method_at_offset(var self, var cls, size_t offset);

var type_method_at_offset(var self, var cls, size_t offset, const char* method);
bool type_implements_method_at_offset(var self, var cls, size_t offset);

struct Header* header(var self);
var header_init(var head, var type, int alloc);

size_t size(var type);

var alloc(var type);
var alloc_raw(var type);
var alloc_root(var type);

#define alloc_stack(T) ((struct T*)header_init( \
  (char[sizeof(struct Header) + sizeof(struct T)]){0}, T, AllocStack))

void dealloc(var self);
void dealloc_raw(var self);
void dealloc_root(var self);

#define $(T, ...) ((struct T*)memcpy( \
  alloc_stack(T), &((struct T){__VA_ARGS__}), sizeof(struct T)))

#define $I(X) $(Int, X)
#define $F(X) $(Float, X)
#define $S(X) $(String, X)
#define $R(X) $(Ref, X)
#define $B(X) $(Box, X)

#define tuple(...) tuple_xp(tuple_in, (_, ##__VA_ARGS__, Terminal))
#define tuple_xp(X, A) X A
#define tuple_in(_, ...) $(Tuple, (var[]){ __VA_ARGS__ })

#define construct(self, ...) construct_with(self, tuple(__VA_ARGS__))
var construct_with(var self, var args);
var destruct(var self);

#define new(T, ...) ((struct T*)new_with(T, tuple(__VA_ARGS__)))
#define new_raw(T, ...) ((struct T*)new_raw_with(T, tuple(__VA_ARGS__)))
#define new_root(T, ...) ((struct T*)new_root_with(T, tuple(__VA_ARGS__)))

var new_with(var type, var args);
var new_raw_with(var type, var args);
var new_root_with(var type, var args);

void del(var self);
void del_raw(var self);
void del_root(var self);

var assign(var self, var obj);
var copy(var self);
void swap(var self, var obj);

int cmp(var self, var obj);
bool eq(var self, var obj);
bool neq(var self, var obj);
bool gt(var self, var obj);
bool lt(var self, var obj);
bool ge(var self, var obj);
bool le(var self, var obj);

uint64_t hash(var self);
uint64_t hash_data(const void* data, size_t num);

var iter_init(var self);
var iter_next(var self, var curr);
var iter_prev(var self, var curr);
var iter_last(var self);
var iter_type(var self);

#define foreach(...) foreach_xp(foreach_in, (__VA_ARGS__))
#define foreach_xp(X, A) X A
#define foreach_in(X, S) for(var \
  __##X = (S), \
  __Iter##X = instance(__##X, Iter), \
  X = ((struct Iter*)(__Iter##X))->iter_init(__##X); \
  X isnt Terminal; \
  X = ((struct Iter*)(__Iter##X))->iter_next(__##X, X))

void push(var self, var obj);
void pop(var self);
void push_at(var self, var obj, var key);
void pop_at(var self, var key);

void sort(var self);
void sort_by(var self, bool(*f)(var,var));

void append(var self, var obj);
void concat(var self, var obj);

var  get(var self, var key);
void set(var self, var key, var val);
bool mem(var self, var key);
void rem(var self, var key);
var key_type(var self);
var val_type(var self);

void resize(var self, size_t n);
size_t len(var self);
bool empty(var self);

char* c_str(var self);
int64_t c_int(var self);
double c_float(var self);

#define range(...) range_stack($(Range, $I(0), 0, 0, 0), tuple(__VA_ARGS__))

#define slice(I, ...) slice_xp(slice_in, (I, ##__VA_ARGS__))
#define slice_xp(X, A) X A
#define slice_in(...) slice_stack( \
  $(Slice, NULL, $(Range, $I(0), 0, 0, 0)), tuple(__VA_ARGS__))

#define reverse(I) slice(I, _, _, $I(-1))
#define filter(I, F) $(Filter, I, F)
#define map(I, F) $(Map, I, NULL, F)

#define zip(...) zip_stack( \
  $(Zip, tuple(__VA_ARGS__), \
  $(Tuple, (var[(sizeof((var[]){__VA_ARGS__})/sizeof(var))+1]){0})))

#define enumerate(I) enumerate_stack(zip(range(), I))

var range_stack(var self, var args);
var slice_stack(var self, var args);
var zip_stack(var self);
var enumerate_stack(var self);

var sopen(var self, var resource, var options);
void sclose(var self);
void sseek(var self, int64_t pos, int origin);
int64_t stell(var self);
void sflush(var self);
bool seof(var self);
size_t sread(var self, void* output, size_t size);
size_t swrite(var self, void* input, size_t size);

void ref(var self, var item);
var deref(var self);

#define call(self, ...) call_with(self, tuple(__VA_ARGS__))
var call_with(var self, var args);

int format_to_va(var self, int pos, const char* fmt, va_list va);
int format_from_va(var self, int pos, const char* fmt, va_list va);

int format_to(var self, int pos, const char* fmt, ...);
int format_from(var self, int pos, const char* fmt, ...);

int show(var self);
int show_to(var self, var out, int pos);

#define print(fmt, ...) print_with(fmt, tuple(__VA_ARGS__))
#define println(fmt, ...) println_with(fmt, tuple(__VA_ARGS__))
#define print_to(out, pos, fmt, ...) \
  print_to_with(out, pos, fmt, tuple(__VA_ARGS__))

int print_with(const char* fmt, var args);
int println_with(const char* fmt, var args);
int print_to_with(var out, int pos, const char* fmt, var args);

int look(var self);
int look_from(var self, var input, int pos);

#define scan(fmt, ...) scan_with(fmt, tuple(__VA_ARGS__))
#define scanln(fmt, ...) scanln_with(fmt, tuple(__VA_ARGS__))
#define scan_from(input, pos, fmt, ...) \
  scan_from_with(input, pos, fmt, tuple(__VA_ARGS__))

int scan_with(const char* fmt, var args);
int scanln_with(const char* fmt, var args);
int scan_from_with(var input, int pos, const char* fmt, var args);

var current(var type);

void start(var self);
void stop(var self);
void join(var self);
bool running(var self);

var start_in(var self);
var stop_in(var self);

#define with(...) with_xp(with_in, (__VA_ARGS__))
#define with_xp(X, A) X A
#define with_in(X, S) for(var X = start_in(S); X isnt NULL; X = stop_in(X))

void lock(var self);
bool lock_try(var self);
void unlock(var self);

#define try { jmp_buf __env; exception_try(&__env); if (!setjmp(__env))

#define catch(...) catch_xp(catch_in, (__VA_ARGS__))
#define catch_xp(X, A) X A
#define catch_in(X, ...) else { exception_try_fail(); } exception_try_end(); } \
  for (var X = exception_catch(tuple(__VA_ARGS__)); \
    X isnt NULL; X = NULL)

#define throw(E, F, ...) exception_throw(E, F, tuple(__VA_ARGS__))

void exception_try(jmp_buf* env);
void exception_try_end(void);
void exception_try_fail(void);
var exception_throw(var obj, const char* fmt, var args);
var exception_catch(var args);

void exception_signals(void);

var exception_object(void);
var exception_message(void);

void mark(var self, var gc, void(*f)(var,void*));

#ifndef CELLO_NGC

extern var GC;

int Cello_Main(int argc, char** argv);
void Cello_Exit(void);

#define main(...) \
  main(int argc, char** argv) { \
    var bottom = NULL; \
    new_raw(GC, $R(&bottom)); \
    atexit(Cello_Exit); \
    return Cello_Main(argc, argv); \
  }; \
  int Cello_Main(__VA_ARGS__)

#endif

#endif


text:
<div class="list-container <?php echo implode( ' ', $classes ); ?>"><?php
    foreach ($items as $item) :
        global $post;
        $post = $item;
        setup_postdata($post);
        $link_target = get_post_meta( $post->ID, THEME_SHORT . '_target', true );
        $link = oxy_get_slide_link( $post );
        $custom_fields = get_post_custom($post->ID);
        $cite  = (isset($custom_fields[THEME_SHORT.'_citation']))? $custom_fields[THEME_SHORT.'_citation'][0]:''; ?>
        <div class="<?php echo implode( ' ', $wrapper_classes ); ?>" data-os-animation="<?php echo $scroll_animation; ?>" data-os-animation-delay="<?php echo $scroll_animation_delay; ?>s"><?php
            if( !empty( $link ) ) : ?>
                <a href="<?php echo $link; ?>" target="<?php echo $link_target; ?>"> <?php
            endif; ?>

                        <?php echo get_the_post_thumbnail( $post->ID, 'thumbnail' ); ?>

<?php echo strip_tags( get_the_content() ); ?>

                    <?php
                    the_title();
                    if( !empty( $cite ) ) {?>
                    <?php
                        echo $cite; ?>

                <?php } ?>

 <?php
            if( !empty( $link ) ) : ?>
                <?php
            endif; ?>

<?php
        if( $testimonial_scroll_animation_timing === 'staggered' ) :
                $scroll_animation_delay += $item_delay;
        endif;
    endforeach; ?>

<?php
wp_reset_postdata(); ?>


text:
obj-m := rf-core/ bebot-chassis-rfs/

SRC := $(shell pwd)

all:
	$(MAKE) -C $(KERNEL_SRC) M=$(SRC)

modules_install:
	$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install

clean:
	rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
	rm -f Module.markers Module.symvers modules.order
	rm -rf .tmp_versions Modules.symvers


text:
<?php

namespace Drupal\webform_example_element\Element;

use Drupal\Core\Render\Element;
use Drupal\Core\Render\Element\FormElement;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provides a 'webform_example_element'.
 *
 * Webform elements are just wrappers around form elements, therefore every
 * webform element must have correspond FormElement.
 *
 * Below is the definition for a custom 'webform_example_element' which just
 * renders a simple text field.
 *
 * @FormElement("webform_example_element")
 *
 * @see \Drupal\Core\Render\Element\FormElement
 * @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21FormElement.php/class/FormElement
 * @see \Drupal\Core\Render\Element\RenderElement
 * @see https://api.drupal.org/api/drupal/namespace/Drupal%21Core%21Render%21Element
 * @see \Drupal\webform_example_element\Element\WebformExampleElement
 */
class WebformExampleElement extends FormElement {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $class = get_class($this);
    return [
      '#input' => TRUE,
      '#size' => 60,
      '#process' => [
        [$class, 'processWebformElementExample'],
        [$class, 'processAjaxForm'],
      ],
      '#element_validate' => [
        [$class, 'validateWebformExampleElement'],
      ],
      '#pre_render' => [
        [$class, 'preRenderWebformExampleElement'],
      ],
      '#theme' => 'input__webform_example_element',
      '#theme_wrappers' => ['form_element'],
    ];
  }

  /**
   * Processes a 'webform_example_element' element.
   */
  public static function processWebformElementExample(&$element, FormStateInterface $form_state, &$complete_form) {
    // Here you can add and manipulate your element's properties and callbacks.
    return $element;
  }

  /**
   * Webform element validation handler for #type 'webform_example_element'.
   */
  public static function validateWebformExampleElement(&$element, FormStateInterface $form_state, &$complete_form) {
    // Here you can add custom validation logic.
  }

  /**
   * Prepares a #type 'email_multiple' render element for theme_element().
   *
   * @param array $element
   *   An associative array containing the properties of the element.
   *   Properties used: #title, #value, #description, #size, #maxlength,
   *   #placeholder, #required, #attributes.
   *
   * @return array
   *   The $element with prepared variables ready for theme_element().
   */
  public static function preRenderWebformExampleElement(array $element) {
    $element['#attributes']['type'] = 'text';
    Element::setAttributes($element, ['id', 'name', 'value', 'size', 'maxlength', 'placeholder']);
    static::setAttributes($element, ['form-text', 'webform-example-element']);
    return $element;
  }

}


text:
namespace base {
class CommandLine;
class MessageLoop;
}

namespace gfx {
class Size;
}

namespace IPC {
class ChannelMojoHost;
}

namespace content {
class AudioInputRendererHost;
class AudioRendererHost;
class BrowserCdmManager;
class BrowserDemuxerAndroid;
class InProcessChildThreadParams;
class MessagePortMessageFilter;
class MojoChildConnection;
class NotificationMessageFilter;
#if defined(ENABLE_WEBRTC)
class P2PSocketDispatcherHost;
#endif
class PermissionServiceContext;
class PeerConnectionTrackerHost;
class RendererMainThread;
class RenderFrameMessageFilter;
class RenderWidgetHelper;
class RenderWidgetHost;
class RenderWidgetHostImpl;
class RenderWidgetHostViewFrameSubscriber;
class StoragePartition;
class StoragePartitionImpl;

namespace mojom {
class StoragePartitionService;
}

typedef base::Thread* (*RendererMainThreadFactoryFunction)(
    const InProcessChildThreadParams& params);

// Implements a concrete RenderProcessHost for the browser process for talking
// to actual renderer processes (as opposed to mocks).
//
// Represents the browser side of the browser <--> renderer communication
// channel. There will be one RenderProcessHost per renderer process.
//
// This object is refcounted so that it can release its resources when all
// hosts using it go away.
//
// This object communicates back and forth with the RenderProcess object
// running in the renderer process. Each RenderProcessHost and RenderProcess
// keeps a list of RenderView (renderer) and WebContentsImpl (browser) which
// are correlated with IDs. This way, the Views and the corresponding ViewHosts
// communicate through the two process objects.
//
// A RenderProcessHost is also associated with one and only one
// StoragePartition.  This allows us to implement strong storage isolation
// because all the IPCs from the RenderViews (renderer) will only ever be able
// to access the partition they are assigned to.
class CONTENT_EXPORT RenderProcessHostImpl
    : public RenderProcessHost,
      public ChildProcessLauncher::Client,
      public ui::GpuSwitchingObserver {
 public:
  RenderProcessHostImpl(BrowserContext* browser_context,
                        StoragePartitionImpl* storage_partition_impl,
                        bool is_for_guests_only);
  ~RenderProcessHostImpl() override;

  // RenderProcessHost implementation (public portion).
  void EnableSendQueue() override;
  bool Init() override;
  int GetNextRoutingID() override;
  void AddRoute(int32_t routing_id, IPC::Listener* listener) override;
  void RemoveRoute(int32_t routing_id) override;
  void AddObserver(RenderProcessHostObserver* observer) override;
  void RemoveObserver(RenderProcessHostObserver* observer) override;
  void ShutdownForBadMessage() override;
  void WidgetRestored() override;
  void WidgetHidden() override;
  int VisibleWidgetCount() const override;
  void AudioStateChanged() override;
  bool IsForGuestsOnly() const override;
  StoragePartition* GetStoragePartition() const override;
  bool Shutdown(int exit_code, bool wait) override;
  bool FastShutdownIfPossible() override;
  base::ProcessHandle GetHandle() const override;
  bool IsReady() const override;
  BrowserContext* GetBrowserContext() const override;
  bool InSameStoragePartition(StoragePartition* partition) const override;
  int GetID() const override;
  bool HasConnection() const override;
  void SetIgnoreInputEvents(bool ignore_input_events) override;
  bool IgnoreInputEvents() const override;
  void Cleanup() override;
  void AddPendingView() override;
  void RemovePendingView() override;
  void SetSuddenTerminationAllowed(bool enabled) override;
  bool SuddenTerminationAllowed() const override;
  IPC::ChannelProxy* GetChannel() override;
  void AddFilter(BrowserMessageFilter* filter) override;
  bool FastShutdownForPageCount(size_t count) override;
  bool FastShutdownStarted() const override;
  base::TimeDelta GetChildProcessIdleTime() const override;
  void FilterURL(bool empty_allowed, GURL* url) override;
#if defined(ENABLE_WEBRTC)
  void EnableAudioDebugRecordings(const base::FilePath& file) override;
  void DisableAudioDebugRecordings() override;
  bool StartWebRTCEventLog(const base::FilePath& file_path) override;
  bool StopWebRTCEventLog() override;
  void SetWebRtcLogMessageCallback(
      base::Callback<void(const std::string&)> callback) override;
  void ClearWebRtcLogMessageCallback() override;
  WebRtcStopRtpDumpCallback StartRtpDump(
      bool incoming,
      bool outgoing,
      const WebRtcRtpPacketCallback& packet_callback) override;
#endif
  void ResumeDeferredNavigation(const GlobalRequestID& request_id) override;
  void NotifyTimezoneChange(const std::string& timezone) override;
  shell::InterfaceProvider* GetRemoteInterfaces() override;
  std::unique_ptr<base::SharedPersistentMemoryAllocator> TakeMetricsAllocator()
      override;
  const base::TimeTicks& GetInitTimeForNavigationMetrics() const override;
#if defined(ENABLE_BROWSER_CDMS)
  scoped_refptr<media::MediaKeys> GetCdm(int render_frame_id,
                                         int cdm_id) const override;
#endif
  bool IsProcessBackgrounded() const override;
  void IncrementWorkerRefCount() override;
  void DecrementWorkerRefCount() override;
  void PurgeAndSuspend() override;

  // IPC::Sender via RenderProcessHost.
  bool Send(IPC::Message* msg) override;

  // IPC::Listener via RenderProcessHost.
  bool OnMessageReceived(const IPC::Message& msg) override;
  void OnChannelConnected(int32_t peer_pid) override;
  void OnChannelError() override;
  void OnBadMessageReceived(const IPC::Message& message) override;

  // ChildProcessLauncher::Client implementation.
  void OnProcessLaunched() override;
  void OnProcessLaunchFailed(int error_code) override;

  scoped_refptr<AudioRendererHost> audio_renderer_host() const;

  // Call this function when it is evident that the child process is actively
  // performing some operation, for example if we just received an IPC message.
  void mark_child_process_activity_time() {
    child_process_activity_time_ = base::TimeTicks::Now();
  }

  // Used to extend the lifetime of the sessions until the render view
  // in the renderer is fully closed. This is static because its also called
  // with mock hosts as input in test cases.
  static void ReleaseOnCloseACK(
      RenderProcessHost* host,
      const SessionStorageNamespaceMap& sessions,
      int view_route_id);

  // Register/unregister the host identified by the host id in the global host
  // list.
  static void RegisterHost(int host_id, RenderProcessHost* host);
  static void UnregisterHost(int host_id);

  // Implementation of FilterURL below that can be shared with the mock class.
  static void FilterURL(RenderProcessHost* rph, bool empty_allowed, GURL* url);

  // Returns true if |host| is suitable for launching a new view with |site_url|
  // in the given |browser_context|.
  static bool IsSuitableHost(RenderProcessHost* host,
                             BrowserContext* browser_context,
                             const GURL& site_url);

  // Returns an existing RenderProcessHost for |url| in |browser_context|,
  // if one exists.  Otherwise a new RenderProcessHost should be created and
  // registered using RegisterProcessHostForSite().
  // This should only be used for process-per-site mode, which can be enabled
  // globally with a command line flag or per-site, as determined by
  // SiteInstanceImpl::ShouldUseProcessPerSite.
  static RenderProcessHost* GetProcessHostForSite(
      BrowserContext* browser_context,
      const GURL& url);

  // Registers the given |process| to be used for any instance of |url|
  // within |browser_context|.
  // This should only be used for process-per-site mode, which can be enabled
  // globally with a command line flag or per-site, as determined by
  // SiteInstanceImpl::ShouldUseProcessPerSite.
  static void RegisterProcessHostForSite(
      BrowserContext* browser_context,
      RenderProcessHost* process,
      const GURL& url);

  static base::MessageLoop* GetInProcessRendererThreadForTesting();

  // This forces a renderer that is running "in process" to shut down.
  static void ShutDownInProcessRenderer();

  static void RegisterRendererMainThreadFactory(
      RendererMainThreadFactoryFunction create);

  // TODO(alokp): Remove after collecting crash data.
  // Temporary checks to verify that all shared workers are terminated.
  // It is suspected that shared workers prevent render process hosts
  // from shutting down: crbug.com/608049
  static void CheckAllWorkersTerminated();

#if defined(OS_ANDROID)
  const scoped_refptr<BrowserDemuxerAndroid>& browser_demuxer_android() {
    return browser_demuxer_android_;
  }
#endif

  RenderFrameMessageFilter* render_frame_message_filter_for_testing() const {
    return render_frame_message_filter_.get();
  }

  MessagePortMessageFilter* message_port_message_filter() const {
    return message_port_message_filter_.get();
  }

  NotificationMessageFilter* notification_message_filter() const {
    return notification_message_filter_.get();
  }

  void set_is_for_guests_only_for_testing(bool is_for_guests_only) {
    is_for_guests_only_ = is_for_guests_only;
  }

  void GetAudioOutputControllers(
      const GetAudioOutputControllersCallback& callback) const override;

#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
  // Launch the zygote early in the browser startup.
  static void EarlyZygoteLaunch();
#endif  // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)

  void RecomputeAndUpdateWebKitPreferences();

 protected:
  // A proxy for our IPC::Channel that lives on the IO thread.
  std::unique_ptr<IPC::ChannelProxy> channel_;

  // True if fast shutdown has been performed on this RPH.
  bool fast_shutdown_started_;

  // True if we've posted a DeleteTask and will be deleted soon.
  bool deleting_soon_;

#ifndef NDEBUG
  // True if this object has deleted itself.
  bool is_self_deleted_;
#endif

  // The count of currently swapped out but pending RenderViews.  We have
  // started to swap these in, so the renderer process should not exit if
  // this count is non-zero.
  int32_t pending_views_;

 private:
  friend class ChildProcessLauncherBrowserTest_ChildSpawnFail_Test;
  friend class VisitRelayingRenderProcessHost;
  class ConnectionFilterImpl;

  std::unique_ptr<IPC::ChannelProxy> CreateChannelProxy(
      const std::string& channel_id);

  // Creates and adds the IO thread message filters.
  void CreateMessageFilters();

  // Registers Mojo interfaces to be exposed to the renderer.
  void RegisterMojoInterfaces();

  void CreateStoragePartitionService(
      mojo::InterfaceRequest<mojom::StoragePartitionService> request);

  // Control message handlers.
  void OnShutdownRequest();
  void SuddenTerminationChanged(bool enabled);
  void OnUserMetricsRecordAction(const std::string& action);
  void OnCloseACK(int old_route_id);

  // Generates a command line to be used to spawn a renderer and appends the
  // results to |*command_line|.
  void AppendRendererCommandLine(base::CommandLine* command_line) const;

  // Copies applicable command line switches from the given |browser_cmd| line
  // flags to the output |renderer_cmd| line flags. Not all switches will be
  // copied over.
  void PropagateBrowserCommandLineToRenderer(
      const base::CommandLine& browser_cmd,
      base::CommandLine* renderer_cmd) const;

  // Inspects the current object state and sets/removes background priority if
  // appropriate. Should be called after any of the involved data members
  // change.
  void UpdateProcessPriority();

  // Creates a PersistentMemoryAllocator and shares it with the renderer
  // process for it to store histograms from that process. The allocator is
  // available for extraction by a SubprocesMetricsProvider in order to
  // report those histograms to UMA.
  void CreateSharedRendererHistogramAllocator();

  // Handle termination of our process.
  void ProcessDied(bool already_dead, RendererClosedDetails* known_details);

  // GpuSwitchingObserver implementation.
  void OnGpuSwitched() override;

#if defined(ENABLE_WEBRTC)
  void OnRegisterAecDumpConsumer(int id);
  void OnUnregisterAecDumpConsumer(int id);
  void RegisterAecDumpConsumerOnUIThread(int id);
  void UnregisterAecDumpConsumerOnUIThread(int id);
  void EnableAecDumpForId(const base::FilePath& file, int id);
  // Sends |file_for_transit| to the render process.
  void SendAecDumpFileToRenderer(int id,
                                 IPC::PlatformFileForTransit file_for_transit);
  void SendDisableAecDumpToRenderer();
  base::FilePath GetAecDumpFilePathWithExtensions(const base::FilePath& file);
#endif

  static void OnMojoError(
      base::WeakPtr<RenderProcessHostImpl> process,
      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
      const std::string& error);

  std::string child_token_;

  std::unique_ptr<MojoChildConnection> mojo_child_connection_;
  ConnectionFilterImpl* connection_filter_ = nullptr;
  shell::mojom::ServicePtr test_service_;
#if defined(OS_ANDROID)
  std::unique_ptr<InterfaceRegistryAndroid> interface_registry_android_;
#endif

  // The registered IPC listener objects. When this list is empty, we should
  // delete ourselves.
  IDMap<IPC::Listener> listeners_;

  // The count of currently visible widgets.  Since the host can be a container
  // for multiple widgets, it uses this count to determine when it should be
  // backgrounded.
  int32_t visible_widgets_;

  // Whether this process currently has backgrounded priority. Tracked so that
  // UpdateProcessPriority() can avoid redundantly setting the priority.
  bool is_process_backgrounded_;

  // Used to allow a RenderWidgetHost to intercept various messages on the
  // IO thread.
  scoped_refptr<RenderWidgetHelper> widget_helper_;

  scoped_refptr<RenderFrameMessageFilter> render_frame_message_filter_;

  // The filter for MessagePort messages coming from the renderer.
  scoped_refptr<MessagePortMessageFilter> message_port_message_filter_;

  // The filter for Web Notification messages coming from the renderer. Holds a
  // closure per notification that must be freed when the notification closes.
  scoped_refptr<NotificationMessageFilter> notification_message_filter_;

  // Used in single-process mode.
  std::unique_ptr<base::Thread> in_process_renderer_;

  // True after Init() has been called. We can't just check channel_ because we
  // also reset that in the case of process termination.
  bool is_initialized_;

  // PlzNavigate
  // Stores the time at which the first call to Init happened.
  base::TimeTicks init_time_;

  // Used to launch and terminate the process without blocking the UI thread.
  std::unique_ptr<ChildProcessLauncher> child_process_launcher_;

  // Messages we queue while waiting for the process handle.  We queue them here
  // instead of in the channel so that we ensure they're sent after init related
  // messages that are sent once the process handle is available.  This is
  // because the queued messages may have dependencies on the init messages.
  std::queue<IPC::Message*> queued_messages_;

  // The globally-unique identifier for this RPH.
  const int id_;

  // A secondary ID used by the Mojo shell to distinguish different incarnations
  // of the same RPH from each other. Unlike |id_| this is not globally unique,
  // but it is guaranteed to change every time Init() is called.
  int instance_id_ = 1;

  BrowserContext* browser_context_;

  // Owned by |browser_context_|.
  StoragePartitionImpl* storage_partition_impl_;

  // The observers watching our lifetime.
  base::ObserverList<RenderProcessHostObserver> observers_;

  // True if the process can be shut down suddenly.  If this is true, then we're
  // sure that all the RenderViews in the process can be shutdown suddenly.  If
  // it's false, then specific RenderViews might still be allowed to be shutdown
  // suddenly by checking their SuddenTerminationAllowed() flag.  This can occur
  // if one WebContents has an unload event listener but another WebContents in
  // the same process doesn't.
  bool sudden_termination_allowed_;

  // Set to true if we shouldn't send input events.  We actually do the
  // filtering for this at the render widget level.
  bool ignore_input_events_;

  // Records the last time we regarded the child process active.
  base::TimeTicks child_process_activity_time_;

  // Indicates whether this RenderProcessHost is exclusively hosting guest
  // RenderFrames.
  bool is_for_guests_only_;

  // Prevents the class from being added as a GpuDataManagerImpl observer more
  // than once.
  bool gpu_observer_registered_;

  // Set if a call to Cleanup is required once the RenderProcessHostImpl is no
  // longer within the RenderProcessHostObserver::RenderProcessExited callbacks.
  bool delayed_cleanup_needed_;

  // Indicates whether RenderProcessHostImpl is currently iterating and calling
  // through RenderProcessHostObserver::RenderProcessExited.
  bool within_process_died_observer_;

  // Forwards power state messages to the renderer process.
  PowerMonitorMessageBroadcaster power_monitor_broadcaster_;

  scoped_refptr<AudioRendererHost> audio_renderer_host_;

  scoped_refptr<AudioInputRendererHost> audio_input_renderer_host_;

#if defined(OS_ANDROID)
  scoped_refptr<BrowserDemuxerAndroid> browser_demuxer_android_;
#endif

#if defined(ENABLE_WEBRTC)
  scoped_refptr<P2PSocketDispatcherHost> p2p_socket_dispatcher_host_;

  // Must be accessed on UI thread.
  std::vector<int> aec_dump_consumers_;

  WebRtcStopRtpDumpCallback stop_rtp_dump_callback_;

  WebRTCEventLogHost webrtc_eventlog_host_;
#endif

  // Forwards messages between WebRTCInternals in the browser process
  // and PeerConnectionTracker in the renderer process.
  // It holds a raw pointer to webrtc_eventlog_host_, and therefore should be
  // defined below it so it is destructed first.
  scoped_refptr<PeerConnectionTrackerHost> peer_connection_tracker_host_;

  int worker_ref_count_;

  // Records the time when the process starts surviving for workers for UMA.
  base::TimeTicks survive_for_worker_start_time_;

  // Records the maximum # of workers simultaneously hosted in this process
  // for UMA.
  int max_worker_count_;

  // Context shared for each mojom::PermissionService instance created for this
  // RPH.
  std::unique_ptr<PermissionServiceContext> permission_service_context_;

  // The memory allocator, if any, in which the renderer will write its metrics.
  std::unique_ptr<base::SharedPersistentMemoryAllocator> metrics_allocator_;

  bool channel_connected_;
  bool sent_render_process_ready_;

#if defined(OS_ANDROID)
  // UI thread is the source of sync IPCs and all shutdown signals.
  // Therefore a proper shutdown event to unblock the UI thread is not
  // possible without massive refactoring shutdown code.
  // Luckily Android never performs a clean shutdown. So explicitly
  // ignore this problem.
  base::WaitableEvent never_signaled_;
#endif

  base::WeakPtrFactory<RenderProcessHostImpl> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl);
};

}  // namespace content

#endif  // CONTENT_BROWSER_RENDERER_HOST_RENDER_PROCESS_HOST_IMPL_H_


text:
WRAP_CLASS("itk::ShapeDetectionLevelSetImageFilter")

  SET(MANAGED_TYPE_TEMPLATE ${MANAGED_ITK_SOURCE_COMMON_PATH}/itkManagedSegmentationLevelSetImageFilter_TYPE.cxx.in)
  SET(MANAGED_WRAPPER_TEMPLATE ${MANAGED_ITK_SOURCE_COMMON_PATH}/itkManagedSegmentationLevelSetImageFilter_WRAPPER.cxx.in)

  FILTER_DIMS(dims 2+)
  FOREACH(d ${dims})
    FOREACH(t ${WRAP_ITK_REAL})
      WRAP_TEMPLATE("${ITKM_I${t}${d}}${ITKM_I${t}${d}}${ITKM_${t}}" "${ITKT_I${t}${d}},${ITKT_I${t}${d}},${ITKT_${t}}")
    ENDFOREACH(t)
  ENDFOREACH(d)

END_WRAP_CLASS()


text:
import parser
import timer

config_file = parser.ConfigFileParser()
config = config_file.get_saved_config_values()
time_printer = timer.Timer()
long_break = 0

while True:
    input("Enter to begin " + str(config['work']) + " minutes of work.")
    time_printer.begin_session(config['work'])
    long_break += 1
    if (long_break < config['long_break_frequency']):
        input("Enter to begin " + str(config['short_break']) + " minutes of break.")
        time_printer.begin_session(config['short_break'])
    else:
        long_break = 0
        input("Enter to begin " + str(config['long_break']) + " minutes of break.")
        time_printer.begin_session(config['long_break'])


text:
@implementation FUGetOperatorsType
// 获取运营商类型
+ (NSString *)getOperatorsType
{
    NSString *SSOperatorsType= @"其他";
    CTTelephonyNetworkInfo *telephonyInfo = [[CTTelephonyNetworkInfo alloc] init];
    CTCarrier *carrier = [telephonyInfo subscriberCellularProvider];

    NSString *currentCountryCode = [carrier mobileCountryCode];
    NSString *mobileNetWorkCode = [carrier mobileNetworkCode];

    if (![currentCountryCode isEqualToString:@"460"]) {
        return SSOperatorsType;
    }

    // 参考 https://en.wikipedia.org/wiki/Mobile_country_code

    if ([mobileNetWorkCode isEqualToString:@"00"] ||
        [mobileNetWorkCode isEqualToString:@"02"] ||
        [mobileNetWorkCode isEqualToString:@"07"] ||
        [mobileNetWorkCode isEqualToString:@"08"]) {

        // 中国移动
        return SSOperatorsType = @"中国移动";
    }

    if ([mobileNetWorkCode isEqualToString:@"01"] ||
        [mobileNetWorkCode isEqualToString:@"06"] ||
        [mobileNetWorkCode isEqualToString:@"09"]) {

        // 中国联通
        return SSOperatorsType = @"中国联通";
    }

    if ([mobileNetWorkCode isEqualToString:@"03"] ||
        [mobileNetWorkCode isEqualToString:@"05"] ||
        [mobileNetWorkCode isEqualToString:@"11"]) {

        // 中国电信
        return SSOperatorsType = @"中国电信";
    }

    if ([mobileNetWorkCode isEqualToString:@"20"]) {

        // 中国铁通
        return SSOperatorsType = @"中国铁通";
    }

    return SSOperatorsType;
}
@end