text: """
  The Sage ZMQ Kernel
  
  Version of the Jupyter kernel when running Sage inside the Jupyter
  notebook or remote Jupyter sessions.
  """
  
  #*****************************************************************************
  #       Copyright (C) 2015 Volker Braun <vbraun.name@gmail.com>
  #
  #  Distributed under the terms of the GNU General Public License (GPL)
  #  as published by the Free Software Foundation; either version 2 of
  #  the License, or (at your option) any later version.
  #                  http://www.gnu.org/licenses/
  #*****************************************************************************
  
  import sys
  from ipykernel.ipkernel import IPythonKernel
  from ipykernel.zmqshell import ZMQInteractiveShell
  from traitlets import Type
  
  from sage.env import SAGE_VERSION
  from sage.repl.interpreter import SageNotebookInteractiveShell
  from sage.repl.ipython_extension import SageJupyterCustomizations
  
  class SageZMQInteractiveShell(SageNotebookInteractiveShell, ZMQInteractiveShell):
      pass
  
  
  class SageKernel(IPythonKernel):
      implementation = 'sage'
      implementation_version = SAGE_VERSION
  
      shell_class = Type(SageZMQInteractiveShell)
  
      def __init__(self, **kwds):
          """
          The Sage Jupyter Kernel
  
          INPUT:
  
          See the Jupyter documentation
  
          EXAMPLES::
  
              sage: from sage.repl.ipython_kernel.kernel import SageKernel
              sage: SageKernel.__new__(SageKernel)
              <sage.repl.ipython_kernel.kernel.SageKernel object at 0x...>
          """
          super(SageKernel, self).__init__(**kwds)
          SageJupyterCustomizations(self.shell)
  
      @property
      def banner(self):
          r"""
          The Sage Banner
  
          The value of this property is displayed in the Jupyter
          notebook.
  
          OUTPUT:
  
          String.
  
          EXAMPLES::
  
              sage: from sage.repl.ipython_kernel.kernel import SageKernel
              sage: sk = SageKernel.__new__(SageKernel)
              sage: sk.banner
              '...SageMath version...'
          """
          from sage.misc.banner import banner_text
          return banner_text()
  
      @property
      def help_links(self):
          r"""
          Help in the Jupyter Notebook
  
          OUTPUT:
  
          See the Jupyter documentation.
  
          .. NOTE::
  
              Urls starting with "kernelspecs" are prepended by the
              browser with the appropriate path.
  
          EXAMPLES::
  
              sage: from sage.repl.ipython_kernel.kernel import SageKernel
              sage: sk = SageKernel.__new__(SageKernel)
              sage: sk.help_links
              [{'text': 'Sage Documentation',
                'url': 'kernelspecs/sagemath/doc/index.html'},
               ...]
          """
          from sage.repl.ipython_kernel.install import SageKernelSpec
          identifier = SageKernelSpec.identifier()
          kernel_url = lambda x: 'kernelspecs/{0}/{1}'.format(identifier, x)
          return [
              {
                  'text': 'Sage Documentation',
                  'url': kernel_url('doc/index.html'),
              },
              {
                  'text': 'Sage Tutorial',
                  'url': kernel_url('doc/tutorial/index.html'),
              },
              {
                  'text': 'Thematic Tutorials',
                  'url': kernel_url('doc/thematic_tutorials/index.html'),
              },
              {
                  'text': 'FAQs',
                  'url': kernel_url('doc/faq/index.html'),
              },
              {
                  'text': 'PREP Tutorials',
                  'url': kernel_url('doc/prep/index.html'),
              },
              {
                  'text': 'Sage Reference',
                  'url': kernel_url('doc/reference/index.html'),
              },
              {
                  'text': "Developer's Guide",
                  'url': kernel_url('doc/developer/index.html'),
              },
              {
                  'text': "Python",
                  'url': "http://docs.python.org/%i.%i" % sys.version_info[:2],
              },
              {
                  'text': "IPython",
                  'url': "http://ipython.org/documentation.html",
              },
              {
                  'text': 'Singular',
                  'url': 'http://www.singular.uni-kl.de/Manual/latest/index.htm',
              },
              {
                  'text': 'GAP',
                  'url': 'http://gap-system.org/Manuals/doc/ref/chap0.html',
              },
              {
                  'text': "NumPy",
                  'url': "http://docs.scipy.org/doc/numpy/reference/",
              },
              {
                  'text': "SciPy",
                  'url': "http://docs.scipy.org/doc/scipy/reference/",
              },
              {
                  'text': "SymPy",
                  'url': 'http://docs.sympy.org/latest/index.html',
              },
              {
                  'text': "Matplotlib",
                  'url': "http://matplotlib.org/contents.html",
              },
              {
                  'text': "Markdown",
                  'url': "http://help.github.com/articles/github-flavored-markdown",
              },
          ]
  
      def pre_handler_hook(self):
          """
          Restore the signal handlers to their default values at Sage
          startup, saving the old handler at the ``saved_sigint_handler``
          attribute. This is needed because Jupyter needs to change the
          ``SIGINT`` handler.
  
          See :trac:`19135`.
  
          TESTS::
  
              sage: from sage.repl.ipython_kernel.kernel import SageKernel
              sage: k = SageKernel.__new__(SageKernel)
              sage: k.pre_handler_hook()
              sage: k.saved_sigint_handler
              <cyfunction python_check_interrupt at ...>
          """
          from cysignals import init_cysignals
          self.saved_sigint_handler = init_cysignals()
  