[sagemath] Initial import (#877651).

pcpa pcpa at fedoraproject.org
Mon Apr 22 17:11:36 UTC 2013


commit 86f823b2b0542dc65bdaae670a63274fa3e502c0
Author: pcpa <paulo.cesar.pereira.de.andrade at gmail.com>
Date:   Mon Apr 22 14:11:03 2013 -0300

    Initial import (#877651).

 .gitignore                                         |    1 +
 Jmol.js                                            | 1663 +++++
 JmolHelp.html                                      |   79 +
 gprc.expect                                        |   11 +
 makecmds.sty                                       |   95 +
 sagemath-4ti2.patch                                |   22 +
 sagemath-buildroot.patch                           |   23 +
 sagemath-cbc.patch                                 |  122 +
 sagemath-cremona.patch                             |   36 +
 sagemath-cryptominisat.patch                       |   23 +
 sagemath-ecl-unicode.patch                         |  100 +
 sagemath-extensions.patch                          |   13 +
 sagemath-fes.patch                                 |   12 +
 sagemath-fplll.patch                               |  194 +
 sagemath-gap-hap.patch                             |   23 +
 sagemath-gmp.patch                                 |   11 +
 sagemath-jmol.patch                                |   30 +
 sagemath-libgap.patch                              |    2 +
 sagemath-libmpc.patch                              |   65 +
 sagemath-lrcalc.patch                              |   12 +
 sagemath-lrslib.patch                              |   15 +
 sagemath-maxima.patch                              |   35 +
 sagemath-maxima.system.patch                       |   12 +
 sagemath-nauty.patch                               |   13 +
 sagemath-nolibgap.patch                            |   55 +
 sagemath-nopari2.6.patch                           |   25 +
 sagemath-pari.patch                                |   41 +
 sagemath-png.patch                                 |   30 +
 sagemath-readonly.patch                            |   20 +
 sagemath-rpmbuild.patch                            |  154 +
 sagemath-sagedoc.patch                             |   80 +
 sagemath-sagenb.patch                              |   72 +
 sagemath-scons.patch                               |   39 +
 sagemath-scripts.patch                             |  783 +++
 sagemath-unpatched_ntl.patch                       |   60 +
 sagemath.spec                                      | 1554 +++++
 sources                                            |    1 +
 testjava.sh                                        |   13 +
 ..._pt_translation_of_a_tour_of_sage_rebase1.patch |  192 +
 trac_12822_pt_translation_of_tutorial.patch        | 6801 ++++++++++++++++++++
 trac_12822_pt_translation_of_tutorial_rev1.patch   |  468 ++
 41 files changed, 13000 insertions(+), 0 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index e69de29..2cb112d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/sage-5.8.tar
diff --git a/Jmol.js b/Jmol.js
new file mode 100644
index 0000000..5258856
--- /dev/null
+++ b/Jmol.js
@@ -0,0 +1,1663 @@
+/* Jmol 12.0 script library Jmol.js 9:48 PM 1/31/2011 Bob Hanson
+
+ checkbox heirarchy -- see http://chemapps.stolaf.edu/jmol/docs/examples-11/check.htm
+
+    based on:
+ *
+ * Copyright (C) 2004-2005  Miguel, Jmol Development, www.jmol.org
+ *
+ * Contact: hansonr at stolaf.edu
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ *  02111-1307  USA.
+ */
+
+// for documentation see www.jmol.org/jslibrary
+
+try{if(typeof(_jmol)!="undefined")exit()
+
+// place "?NOAPPLET" on your command line to check applet control action with a textarea
+// place "?JMOLJAR=xxxxx" to use a specific jar file
+
+// bob hanson -- jmolResize(w,h) -- resizes absolutely or by percent (w or h 0.5 means 50%)
+//    angel herraez -- update of jmolResize(w,h,targetSuffix) so it is not tied to first applet
+// bob hanson -- jmolEvaluate -- evaluates molecular math 8:37 AM 2/23/2007
+// bob hanson -- jmolScriptMessage -- returns all "scriptStatus" messages 8:37 AM 2/23/2007
+// bob hanson -- jmolScriptEcho -- returns all "scriptEcho" messages 8:37 AM 2/23/2007
+// bob hanson -- jmolScriptWait -- 11:31 AM 5/2/2006
+// bob hanson -- remove trailing separatorHTML in radio groups -- 12:18 PM 5/6/2006
+// bob hanson -- adds support for dynamic DOM script nodes 7:04 AM 5/19/2006
+// bob hanson -- adds try/catch for wiki - multiple code passes 7:05 AM 5/19/2006
+// bob hanson -- auto-initiates to defaultdir/defaultjar -- change as desired.
+// bob hanson -- adding save/restore orientation w/ and w/o delay 11:49 AM 5/25/2006
+// bob hanson -- adding AjaxJS service 11:16 AM 6/3/2006
+// bob hanson -- fix for iframes not available for finding applet
+// bob hanson -- added applet fake ?NOAPPLET URL flag
+// bob hanson -- added jmolSetCallback(calbackName, funcName) 3:32 PM 6/13/2006
+//			used PRIOR to jmolApplet() or jmolAppletInline()
+//               added 4th array element in jmolRadioGroup -- title
+//               added <span> and id around link, checkbox, radio, menu
+//               fixing AJAX loads for MSIE/Opera-Mozilla incompatibility
+//            -- renamed Jmol-11.js from Jmol-new.js; JmolApplet.jar from JmolAppletProto.jar
+//	 	 renamed Jmol.js for Jmol 11 distribution
+//            -- modified jmolRestoreOrientation() to be immediate, no 1-second delay
+// bob hanson -- jmolScriptWait always returns a string -- 11:23 AM 9/16/2006
+// bh         -- jmolCommandInput()
+// bh         -- jmolSetTranslation(TF) -- forces translation even if there might be message callback issues
+// bh         -- minor fixes suggested by Angel
+// bh         -- adds jmolSetSyncId() and jmolGetSyncId()
+// bh 3/2008  -- adds jmolAppendInlineScript() and jmolAppendInlineArray()
+// bh 3/2008  -- fixes IE7 bug in relation to jmolLoadInlineArray()
+// bh 6/2008  -- adds jmolSetAppletWindow()
+// Angel H. 6/2008  -- added html <label> tags to checkboxes and radio buttons [in jmolCheckbox() and _jmolRadio() functions]
+// bh 7/2008  -- code fix "for(i..." not "for(var i..."
+// bh 12/2008 -- jmolLoadInline, jmolLoadInlineArray, jmolLoadInlineScript, jmolAppendInlineScript, jmolAppendInlineArray all return error message or null (Jmol 11.7.16)
+// bh 12/2008 -- jmolScriptWaitOutput() -- waits for script to complete and delivers output normally sent to console
+
+// bh 5/2009  -- Support for XHTML using jmolSetXHTML(id)
+// ah & bh 6/2009 -- New jmolResizeApplet() more flexible, similar to jmolApplet() size syntax
+// bh 11/2009 -- care in accessing top.document
+// bh 12/2009 -- added jmolSetParameter(name, value)
+// bh 12/2009 -- added PARAMS=name:value;name:value;name:value... for command line
+// bh 12/2009 -- overhaul of target checking
+// bh 1/2010  -- all _xxxx() methods ALWAYS have complete argument list
+// bh 1/2010  -- adds option to run a JavaScript function from any Jmol control. 
+//               This is accomplished by passing an array rather than a script:
+//               jmolHref([myfunc,"my param 1", "my param 2"], "testing")
+//               function myfunc(jmolControlObject, [myfunc,"my param 1", "my param 2"], target){...}
+//               and allows much more flexibility with responding to controls
+// bh 4/2010  -- added jmolSetMemoryMb(nMb)
+// ah 1/2011  -- wider detection of browsers; more browsers now use the object tag instead of the applet tag; 
+//               fix of object tag (removed classid) accounts for change of behavior in Chrome
+
+var defaultdir = "."
+var defaultjar = "JmolApplet.jar"
+
+
+// Note added 12:41 PM 9/21/2008 by Bob Hanson, hansonr at stolaf.edu:
+
+// JMOLJAR=xxxxx.jar on the URL for this page will override
+// the JAR file specified in the jmolInitialize() call.
+
+// The idea is that it can be very useful to test a web page with different JAR files
+// Or for an expert user to substitute a signed applet for an unsigned one
+// so as to use a broader range of models or to create JPEG files, for example.
+
+// If the JAR file is not in the current directory (has any sort of "/" in its name)
+// then the user is presented with a warning and asked whether it is OK to change Jar files.
+// The default action, if the user just presses "OK" is to NOT allow the change. 
+// The user must type the word "yes" in the prompt box for the change to be approved.
+
+// If you don't want people to be able to switch in their own JAR file on your page,
+// simply set this next line to read "var allowJMOLJAR = false".
+
+
+var undefined; // for IE 5 ... wherein undefined is undefined
+
+////////////////////////////////////////////////////////////////
+// Basic Scripting infrastruture
+////////////////////////////////////////////////////////////////
+
+function jmolInitialize(codebaseDirectory, fileNameOrUseSignedApplet) {
+  if (_jmol.initialized)
+    return;
+  _jmol.initialized = true;
+  if(_jmol.jmoljar) {
+    var f = _jmol.jmoljar;
+    if (f.indexOf("/") >= 0) {
+      alert ("This web page URL is requesting that the applet used be " + f + ". This is a possible security risk, particularly if the applet is signed, because signed applets can read and write files on your local machine or network.")
+      var ok = prompt("Do you want to use applet " + f + "? ","yes or no")
+      if (ok == "yes") {
+        codebaseDirectory = f.substring(0, f.lastIndexOf("/"));
+        fileNameOrUseSignedApplet = f.substring(f.lastIndexOf("/") + 1);
+      } else {
+	_jmolGetJarFilename(fileNameOrUseSignedApplet);
+        alert("The web page URL was ignored. Continuing using " + _jmol.archivePath + ' in directory "' + codebaseDirectory + '"');
+      }
+    } else {
+      fileNameOrUseSignedApplet = f;
+    }
+  }
+  _jmolSetCodebase(codebaseDirectory);
+  _jmolGetJarFilename(fileNameOrUseSignedApplet);
+  _jmolOnloadResetForms();
+}
+
+function jmolSetTranslation(TF) {
+  _jmol.params.doTranslate = ''+TF;
+}
+
+function jmolToSigned(){
+    _jmolGetJarFilename(true);
+}
+    
+function _jmolGetJarFilename(fileNameOrFlag) {
+  _jmol.archivePath =
+    (typeof(fileNameOrFlag) == "string"  ? fileNameOrFlag : (fileNameOrFlag ?  "JmolAppletSigned" : "JmolApplet") + "0.jar");
+}
+
+function jmolSetDocument(doc) {
+  _jmol.currentDocument = doc;
+}
+
+function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) {
+  _jmolInitCheck();
+  _jmol.params.boxbgcolor = boxbgcolor;
+  if (boxfgcolor)
+    _jmol.params.boxfgcolor = boxfgcolor
+  else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF")
+    _jmol.params.boxfgcolor = "black";
+  else
+    _jmol.params.boxfgcolor = "white";
+  if (progresscolor)
+    _jmol.params.progresscolor = progresscolor;
+  if (_jmol.debugAlert)
+    alert(" boxbgcolor=" + _jmol.params.boxbgcolor +
+          " boxfgcolor=" + _jmol.params.boxfgcolor +
+          " progresscolor=" + _jmol.params.progresscolor);
+}
+
+function jmolSetAppletWindow(w) {
+  _jmol.appletWindow = w;
+}
+
+function jmolApplet(size, script, nameSuffix) {
+  _jmolInitCheck();
+  return _jmolApplet(size, null, script, nameSuffix);
+}
+
+////////////////////////////////////////////////////////////////
+// Basic controls
+////////////////////////////////////////////////////////////////
+
+// undefined means it wasn't there; null means it was explicitly listed as null (so as to skip it)
+
+function jmolButton(script, label, id, title) {
+  _jmolInitCheck();
+  id != undefined && id != null || (id = "jmolButton" + _jmol.buttonCount);
+  label != undefined && label != null || (label = script.substring(0, 32));
+  ++_jmol.buttonCount;
+  var scriptIndex = _jmolAddScript(script);
+  var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='button' name='" + id + "' id='" + id +
+          "' value='" + label +
+          "' onclick='_jmolClick(this," + scriptIndex + _jmol.targetText +
+          ")' onmouseover='_jmolMouseOver(" + scriptIndex +
+          ");return true' onmouseout='_jmolMouseOut()' " +
+          _jmol.buttonCssText + " /></span>";
+  if (_jmol.debugAlert)
+    alert(t);
+  return _jmolDocumentWrite(t);
+}
+
+function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked,
+                      labelHtml, isChecked, id, title) {
+  _jmolInitCheck();
+  id != undefined && id != null || (id = "jmolCheckbox" + _jmol.checkboxCount);
+  ++_jmol.checkboxCount;
+  if (scriptWhenChecked == undefined || scriptWhenChecked == null ||
+      scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) {
+    alert("jmolCheckbox requires two scripts");
+    return;
+  }
+  if (labelHtml == undefined || labelHtml == null) {
+    alert("jmolCheckbox requires a label");
+    return;
+  }
+  var indexChecked = _jmolAddScript(scriptWhenChecked);
+  var indexUnchecked = _jmolAddScript(scriptWhenUnchecked);
+  var eospan = "</span>"
+  var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='checkbox' name='" + id + "' id='" + id +
+          "' onclick='_jmolCbClick(this," +
+          indexChecked + "," + indexUnchecked + _jmol.targetText +
+          ")' onmouseover='_jmolCbOver(this," + indexChecked + "," +
+          indexUnchecked +
+          ");return true' onmouseout='_jmolMouseOut()' " +
+	  (isChecked ? "checked='true' " : "")+ _jmol.checkboxCssText + " />" 
+  if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
+	t += eospan
+	eospan = "";
+  }
+  t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan;
+  if (_jmol.debugAlert)
+    alert(t);
+  return _jmolDocumentWrite(t);
+}
+
+function jmolStartNewRadioGroup() {
+  ++_jmol.radioGroupCount;
+}
+
+function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName, id, title) {
+  /*
+
+    array: [radio1,radio2,radio3...]
+    where radioN = ["script","label",isSelected,"id","title"]
+
+  */
+
+  _jmolInitCheck();
+  var type = typeof arrayOfRadioButtons;
+  if (type != "object" || type == null || ! arrayOfRadioButtons.length) {
+    alert("invalid arrayOfRadioButtons");
+    return;
+  }
+  separatorHtml != undefined && separatorHtml != null || (separatorHtml = "&nbsp; ");
+  var len = arrayOfRadioButtons.length;
+  jmolStartNewRadioGroup();
+  groupName || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));
+  var t = "<span id='"+(id ? id : groupName)+"'>";
+  for (var i = 0; i < len; ++i) {
+    if (i == len - 1)
+      separatorHtml = "";
+    var radio = arrayOfRadioButtons[i];
+    type = typeof radio;
+    if (type == "object") {
+      t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName, (radio.length > 3 ? radio[3]: (id ? id : groupName)+"_"+i), (radio.length > 4 ? radio[4] : 0), title);
+    } else {
+      t += _jmolRadio(radio, null, null, separatorHtml, groupName, (id ? id : groupName)+"_"+i, title);
+    }
+  }
+  t+="</span>"
+  if (_jmol.debugAlert)
+    alert(t);
+  return _jmolDocumentWrite(t);
+}
+
+
+function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
+  _jmolInitCheck();
+  if (_jmol.radioGroupCount == 0)
+    ++_jmol.radioGroupCount;
+  var t = _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, (id ? id : groupName + "_" + _jmol.radioCount), title ? title : 0);
+  if (_jmol.debugAlert)
+    alert(t);
+  return _jmolDocumentWrite(t);
+}
+
+function jmolLink(script, label, id, title) {
+  _jmolInitCheck();
+  id != undefined && id != null || (id = "jmolLink" + _jmol.linkCount);
+  label != undefined && label != null || (label = script.substring(0, 32));
+  ++_jmol.linkCount;
+  var scriptIndex = _jmolAddScript(script);
+  var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><a name='" + id + "' id='" + id + 
+          "' href='javascript:_jmolClick(this," + scriptIndex + _jmol.targetText + ");' onmouseover='_jmolMouseOver(" + scriptIndex +
+          ");return true;' onmouseout='_jmolMouseOut()' " +
+          _jmol.linkCssText + ">" + label + "</a></span>";
+  if (_jmol.debugAlert)
+    alert(t);
+  return _jmolDocumentWrite(t);
+}
+
+function jmolCommandInput(label, size, id, title) {
+  _jmolInitCheck();
+  id != undefined && id != null || (id = "jmolCmd" + _jmol.cmdCount);
+  label != undefined && label != null || (label = "Execute");
+  size != undefined && !isNaN(size) || (size = 60);
+  ++_jmol.cmdCount;
+  var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='" + id + "' id='" + id + 
+          "' size='"+size+"' onkeypress='_jmolCommandKeyPress(event,\""+id+"\"" + _jmol.targetText + ")'><input type=button value = '"+label+"' onclick='jmolScript(document.getElementById(\""+id+"\").value" + _jmol.targetText + ")' /></span>";
+  if (_jmol.debugAlert)
+    alert(t);
+  return _jmolDocumentWrite(t);
+}
+
+function _jmolCommandKeyPress(e, id, target) {
+	var keycode = (window.event ? window.event.keyCode : e ? e.which : 0);
+	if (keycode == 13) {
+		var inputBox = document.getElementById(id)
+		_jmolScriptExecute(inputBox, inputBox.value, target)
+	}
+}
+
+function _jmolScriptExecute(element,script,target) {
+	if (typeof(script) == "object")
+		script[0](element, script, target)
+	else
+		jmolScript(script, target) 
+}
+
+function jmolMenu(arrayOfMenuItems, size, id, title) {
+  _jmolInitCheck();
+  id != undefined && id != null || (id = "jmolMenu" + _jmol.menuCount);
+  ++_jmol.menuCount;
+  var type = typeof arrayOfMenuItems;
+  if (type != null && type == "object" && arrayOfMenuItems.length) {
+    var len = arrayOfMenuItems.length;
+    if (typeof size != "number" || size == 1)
+      size = null;
+    else if (size < 0)
+      size = len;
+    var sizeText = size ? " size='" + size + "' " : "";
+    var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><select name='" + id + "' id='" + id +
+            "' onChange='_jmolMenuSelected(this" + _jmol.targetText + ")'" +
+            sizeText + _jmol.menuCssText + ">";
+    for (var i = 0; i < len; ++i) {
+      var menuItem = arrayOfMenuItems[i];
+      type = typeof menuItem;
+      var script, text;
+      var isSelected = undefined;
+      if (type == "object" && menuItem != null) {
+        script = menuItem[0];
+        text = menuItem[1];
+        isSelected = menuItem[2];
+      } else {
+        script = text = menuItem;
+      }
+      text != undefined && text != null || (text = script);		
+      if (script=="#optgroup") {
+        t += "<optgroup label='" + text + "'>";	  
+	  } else if (script=="#optgroupEnd") {
+        t += "</optgroup>";	  
+	  } else {		
+        var scriptIndex = _jmolAddScript(script);
+        var selectedText = isSelected ? "' selected='true'>" : "'>";
+        t += "<option value='" + scriptIndex + selectedText + text + "</option>";
+      }
+    }
+    t += "</select></span>";
+    if (_jmol.debugAlert)
+      alert(t);
+    return _jmolDocumentWrite(t);
+  }
+}
+
+function jmolHtml(html) {
+  return _jmolDocumentWrite(html);
+}
+
+function jmolBr() {
+  return _jmolDocumentWrite("<br />");
+}
+
+////////////////////////////////////////////////////////////////
+// advanced scripting functions
+////////////////////////////////////////////////////////////////
+
+function jmolDebugAlert(enableAlerts) {
+  _jmol.debugAlert = (enableAlerts == undefined || enableAlerts)
+}
+
+function jmolAppletInline(size, inlineModel, script, nameSuffix) {
+  _jmolInitCheck();
+  return _jmolApplet(size, _jmolSterilizeInline(inlineModel),
+                     script, nameSuffix);
+}
+
+function jmolSetTarget(targetSuffix) {
+  _jmol.targetSuffix = targetSuffix;
+  _jmol.targetText = targetSuffix ? ",\"" + targetSuffix + "\"" : ",0";
+}
+
+function jmolScript(script, targetSuffix) {
+  if (script) {
+    _jmolCheckBrowser();
+    if (targetSuffix == "all") {
+      with (_jmol) {
+	for (var i = 0; i < appletSuffixes.length; ++i) {
+	  var applet = _jmolGetApplet(appletSuffixes[i]);
+          if (applet) applet.script(script);
+        }
+      }
+    } else {
+      var applet=_jmolGetApplet(targetSuffix);
+      if (applet) applet.script(script);
+    }
+  }
+}
+
+function jmolLoadInline(model, targetSuffix) {
+  if (!model)return "ERROR: NO MODEL"
+  var applet=_jmolGetApplet(targetSuffix);
+  if (!applet)return "ERROR: NO APPLET"
+  if (typeof(model) == "string")
+    return applet.loadInlineString(model, "", false);
+  else
+    return applet.loadInlineArray(model, "", false);
+}
+
+
+function jmolLoadInlineScript(model, script, targetSuffix) {
+  if (!model)return "ERROR: NO MODEL"
+  var applet=_jmolGetApplet(targetSuffix);
+  if (!applet)return "ERROR: NO APPLET"
+  return applet.loadInlineString(model, script, false);
+}
+
+
+function jmolLoadInlineArray(ModelArray, script, targetSuffix) {
+  if (!model)return "ERROR: NO MODEL"
+  script || (script="")
+  var applet=_jmolGetApplet(targetSuffix);
+  if (!applet)return "ERROR: NO APPLET"
+  try {
+    return applet.loadInlineArray(ModelArray, script, false);
+  } catch (err) {
+    //IE 7 bug
+    return applet.loadInlineString(ModelArray.join("\n"), script, false);
+  }
+}
+
+function jmolAppendInlineArray(ModelArray, script, targetSuffix) {
+  if (!model)return "ERROR: NO MODEL"
+  script || (script="")
+  var applet=_jmolGetApplet(targetSuffix);
+  if (!applet)return "ERROR: NO APPLET"
+  try {
+    return applet.loadInlineArray(ModelArray, script, true);
+  } catch (err) {
+    //IE 7 bug
+    return applet.loadInlineString(ModelArray.join("\n"), script, true);
+  }
+}
+
+function jmolAppendInlineScript(model, script, targetSuffix) {
+  if (!model)return "ERROR: NO MODEL"
+  var applet=_jmolGetApplet(targetSuffix);
+  if (!applet)return "ERROR: NO APPLET"
+  return applet.loadInlineString(model, script, true);
+}
+
+function jmolCheckBrowser(action, urlOrMessage, nowOrLater) {
+  if (typeof action == "string") {
+    action = action.toLowerCase();
+    action == "alert" || action == "redirect" || action == "popup" || (action = null);
+  }
+  if (typeof action != "string")
+    alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
+          "action must be 'alert', 'redirect', or 'popup'");
+  else {
+    if (typeof urlOrMessage != "string")
+      alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
+            "urlOrMessage must be a string");
+    else {
+      _jmol.checkBrowserAction = action;
+      _jmol.checkBrowserUrlOrMessage = urlOrMessage;
+    }
+  }
+  if (typeof nowOrLater == "string" && nowOrLater.toLowerCase() == "now")
+    _jmolCheckBrowser();
+}
+
+////////////////////////////////////////////////////////////////
+// Cascading Style Sheet Class support
+////////////////////////////////////////////////////////////////
+
+function jmolSetAppletCssClass(appletCssClass) {
+  if (_jmol.hasGetElementById) {
+    _jmol.appletCssClass = appletCssClass;
+    _jmol.appletCssText = appletCssClass ? "class='" + appletCssClass + "' " : "";
+  }
+}
+
+function jmolSetButtonCssClass(buttonCssClass) {
+  if (_jmol.hasGetElementById) {
+    _jmol.buttonCssClass = buttonCssClass;
+    _jmol.buttonCssText = buttonCssClass ? "class='" + buttonCssClass + "' " : "";
+  }
+}
+
+function jmolSetCheckboxCssClass(checkboxCssClass) {
+  if (_jmol.hasGetElementById) {
+    _jmol.checkboxCssClass = checkboxCssClass;
+    _jmol.checkboxCssText = checkboxCssClass ? "class='" + checkboxCssClass + "' " : "";
+  }
+}
+
+function jmolSetRadioCssClass(radioCssClass) {
+  if (_jmol.hasGetElementById) {
+    _jmol.radioCssClass = radioCssClass;
+    _jmol.radioCssText = radioCssClass ? "class='" + radioCssClass + "' " : "";
+  }
+}
+
+function jmolSetLinkCssClass(linkCssClass) {
+  if (_jmol.hasGetElementById) {
+    _jmol.linkCssClass = linkCssClass;
+    _jmol.linkCssText = linkCssClass ? "class='" + linkCssClass + "' " : "";
+  }
+}
+
+function jmolSetMenuCssClass(menuCssClass) {
+  if (_jmol.hasGetElementById) {
+    _jmol.menuCssClass = menuCssClass;
+    _jmol.menuCssText = menuCssClass ? "class='" + menuCssClass + "' " : "";
+  }
+}
+
+////////////////////////////////////////////////////////////////
+// functions for INTERNAL USE ONLY which are subject to change
+// use at your own risk ... you have been WARNED!
+////////////////////////////////////////////////////////////////
+var _jmol = {
+  currentDocument: document,
+
+  debugAlert: false,
+  
+  codebase: "",
+  modelbase: ".",
+  
+  appletCount: 0,
+  appletSuffixes: [],
+  appletWindow: null,
+  allowedJmolSize: [25, 2048, 300],   // min, max, default (pixels)
+	  /*  By setting the _jmol.allowedJmolSize[] variable in the webpage 
+	      before calling jmolApplet(), limits for applet size can be overriden.
+		    2048 standard for GeoWall (http://geowall.geo.lsa.umich.edu/home.html)
+	  */  
+  buttonCount: 0,
+  checkboxCount: 0,
+  linkCount: 0,
+  cmdCount: 0,
+  menuCount: 0,
+  radioCount: 0,
+  radioGroupCount: 0,
+  
+  appletCssClass: null,
+  appletCssText: "",
+  buttonCssClass: null,
+  buttonCssText: "",
+  checkboxCssClass: null,
+  checkboxCssText: "",
+  java_arguments: "-Xmx512m",
+  radioCssClass: null,
+  radioCssText: "",
+  linkCssClass: null,
+  linkCssText: "",
+  menuCssClass: null,
+  menuCssText: "",
+  
+  targetSuffix: 0,
+  targetText: ",0",
+  scripts: [""],
+  params: {
+	syncId: ("" + Math.random()).substring(3),
+	progressbar: "true",
+	progresscolor: "blue",
+	boxbgcolor: "black",
+	boxfgcolor: "white",
+	boxmessage: "Downloading JmolApplet ..."
+  },
+  ua: navigator.userAgent.toLowerCase(),
+  // uaVersion: parseFloat(navigator.appVersion),  // not used
+  
+  os: "unknown",
+  browser: "unknown",
+  browserVersion: 0,
+  hasGetElementById: !!document.getElementById,
+  isJavaEnabled: navigator.javaEnabled(),
+  // isNetscape47Win: false,  // not used, N4.7 is no longer supported even for detection
+  useIEObject: false,
+  useHtml4Object: false,
+  
+  windowsClassId: "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93",
+  windowsCabUrl:
+   "http://java.sun.com/update/1.6.0/jinstall-6u22-windows-i586.cab",
+
+  isBrowserCompliant: false,
+  isJavaCompliant: false,
+  isFullyCompliant: false,
+
+  initialized: false,
+  initChecked: false,
+  
+  browserChecked: false,
+  checkBrowserAction: "alert",
+  checkBrowserUrlOrMessage: null,
+
+  archivePath: null, // JmolApplet0.jar OR JmolAppletSigned0.jar
+
+  previousOnloadHandler: null,
+
+  jmoljar: null,  
+  useNoApplet: false,
+
+  ready: {}
+}
+
+with (_jmol) {
+  function _jmolTestUA(candidate) {
+    var ua = _jmol.ua;
+    var index = ua.indexOf(candidate);
+    if (index < 0)
+      return false;
+    _jmol.browser = candidate;
+    _jmol.browserVersion = parseFloat(ua.substring(index+candidate.length+1));
+    return true;
+  }
+  
+  function _jmolTestOS(candidate) {
+    if (_jmol.ua.indexOf(candidate) < 0)
+      return false;
+    _jmol.os = candidate;
+    return true;
+  }
+  
+  _jmolTestUA("konqueror") ||
+  _jmolTestUA("webkit") ||
+  _jmolTestUA("omniweb") ||
+  _jmolTestUA("opera") ||
+  _jmolTestUA("webtv") ||
+  _jmolTestUA("icab") ||
+  _jmolTestUA("msie") ||
+  (_jmol.ua.indexOf("compatible") < 0 && _jmolTestUA("mozilla")); //Netscape, Mozilla, Seamonkey, Firefox and anything assimilated
+  
+  _jmolTestOS("linux") ||
+  _jmolTestOS("unix") ||
+  _jmolTestOS("mac") ||
+  _jmolTestOS("win");
+
+  isBrowserCompliant = hasGetElementById;
+  // known exceptions (old browsers):
+  if (browser == "opera" && browserVersion <= 7.54 && os == "mac" 
+      || browser == "webkit" && browserVersion < 125.12
+      || browser == "msie" && os == "mac" 
+      || browser == "konqueror" && browserVersion <= 3.3
+    ) {
+    isBrowserCompliant = false;
+  }
+
+  // possibly more checks in the future for this
+  isJavaCompliant = isJavaEnabled;
+
+  isFullyCompliant = isBrowserCompliant && isJavaCompliant;
+
+  useIEObject = (os == "win" && browser == "msie" && browserVersion >= 5.5);
+  useHtml4Object =
+   (browser == "mozilla" && browserVersion >= 5) ||
+   (browser == "opera" && browserVersion >= 8) ||
+   (browser == "webkit" && browserVersion >= 412.2);
+ try {
+  if (top.location.search.indexOf("JMOLJAR=")>=0)
+    jmoljar = top.location.search.split("JMOLJAR=")[1].split("&")[0];
+ } catch(e) {
+  // can't access top.location
+ }
+ try {
+  useNoApplet = (top.location.search.indexOf("NOAPPLET")>=0);
+ } catch(e) {
+  // can't access top.document
+ }
+}
+
+function jmolSetMemoryMb(nMb) {
+  _jmol.java_arguments = "-Xmx" + Math.round(nMb) + "m"
+}
+
+function jmolSetParameter(name,value) {
+  _jmol.params[name] = value
+}
+
+function jmolSetCallback(callbackName,funcName) {
+  _jmol.params[callbackName] = funcName
+}
+
+ try {
+// note this is done FIRST, so it cannot override a setting done by the developer
+  if (top.location.search.indexOf("PARAMS=")>=0) {
+    var pars = unescape(top.location.search.split("PARAMS=")[1].split("&")[0]).split(";");
+    for (var i = 0; i < pars.length; i++) {
+      var p = pars[i].split(":");
+      jmolSetParameter(p[0],p[1]);
+    }
+  }
+ } catch(e) {
+  // can't access top.location
+ }
+
+function jmolSetSyncId(n) {
+  return _jmol.params["syncId"] = n
+}
+
+function jmolGetSyncId() {
+  return _jmol.params["syncId"]
+}
+
+function jmolSetLogLevel(n) {
+  _jmol.params.logLevel = ''+n;
+}
+
+	/*  AngelH, mar2007:
+		By (re)setting these variables in the webpage before calling jmolApplet(), 
+		a custom message can be provided (e.g. localized for user's language) when no Java is installed.
+	*/
+if (noJavaMsg==undefined) var noJavaMsg = 
+        "You do not have Java applets enabled in your web browser, or your browser is blocking this applet.<br />\n" +
+        "Check the warning message from your browser and/or enable Java applets in<br />\n" +
+        "your web browser preferences, or install the Java Runtime Environment from <a href='http://www.java.com'>www.java.com</a><br />";
+if (noJavaMsg2==undefined) var noJavaMsg2 = 
+        "You do not have the<br />\n" +
+        "Java Runtime Environment<br />\n" +
+        "installed for applet support.<br />\n" +
+        "Visit <a href='http://www.java.com'>www.java.com</a>";
+function _jmolApplet(size, inlineModel, script, nameSuffix) {
+	/*  AngelH, mar2007
+		Fixed percent / pixel business, to avoid browser errors:
+		put "px" where needed, avoid where not.
+
+	    Bob Hanson, 1/2010
+		Fixed inline escape changing returns to |		
+	*/
+  with (_jmol) {
+    nameSuffix == undefined && (nameSuffix = appletCount);
+    appletSuffixes.push(nameSuffix);
+    ++appletCount;
+    script || (script = "select *");
+    var sz = _jmolGetAppletSize(size);
+    var widthAndHeight = " width='" + sz[0] + "' height='" + sz[1] + "' ";
+    var tHeader, tFooter;
+    codebase || jmolInitialize(".");
+    if (useIEObject || useHtml4Object) {
+      params.archive = archivePath;
+      params.mayscript = 'true';
+      params.codebase = codebase;
+      params.code = 'JmolApplet';
+      tHeader = 
+        "<object name='jmolApplet" + nameSuffix +
+        "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
+				widthAndHeight + "\n";
+      tFooter = "</object>";
+    }
+    if (java_arguments)
+      params.java_arguments = java_arguments;
+    if (useIEObject) { // use MSFT IE6 object tag with .cab file reference
+      tHeader += " classid='" + windowsClassId + "'\n" +
+      (windowsCabUrl ? " codebase='" + windowsCabUrl + "'\n" : "") + ">\n";
+    } else if (useHtml4Object) { // use HTML4 object tag
+      tHeader += " type='application/x-java-applet'\n>\n";
+				/*	" classid='java:JmolApplet'\n" +	AH removed this
+				  Chromium Issue 62076: 	Java Applets using an <object> with a classid paramater don't load.
+					http://code.google.com/p/chromium/issues/detail?id=62076
+					They say this is the correct behavior according to the spec, and there's no indication at this point 
+					that WebKit will be changing the handling, so eventually Safari will acquire this behavior too.
+					Removing the classid parameter seems to be well tolerated by all browsers (even IE!).
+				*/
+    } else { // use applet tag
+      tHeader = 
+        "<applet name='jmolApplet" + nameSuffix +
+        "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
+				widthAndHeight + "\n" +
+        " code='JmolApplet'" +
+        " archive='" + archivePath + "' codebase='" + codebase + "'\n" +
+        " mayscript='true'>\n";
+      tFooter = "</applet>";
+    }
+    var visitJava;
+    if (useIEObject || useHtml4Object) {
+		var szX = "width:" + sz[0]
+		if ( szX.indexOf("%")==-1 ) szX+="px" 
+		var szY = "height:" + sz[1]
+		if ( szY.indexOf("%")==-1 ) szY+="px" 
+      visitJava =
+        "<p style='background-color:yellow; color:black; " +
+		szX + ";" + szY + ";" +
+        // why doesn't this vertical-align work?
+	"text-align:center;vertical-align:middle;'>\n" +
+		noJavaMsg +
+        "</p>";
+    } else {
+      visitJava =
+        "<table bgcolor='yellow'><tr>" +
+        "<td align='center' valign='middle' " + widthAndHeight + "><font color='black'>\n" +
+		noJavaMsg2 +
+        "</font></td></tr></table>";
+    }
+    params.loadInline = (inlineModel ? inlineModel : "");
+    params.script = (script ? _jmolSterilizeScript(script) : "");
+    var t = tHeader + _jmolParams() + visitJava + tFooter;
+    jmolSetTarget(nameSuffix);
+    ready["jmolApplet" + nameSuffix] = false;
+    if (_jmol.debugAlert)
+      alert(t);
+    return _jmolDocumentWrite(t);
+  }
+}
+
+function _jmolParams() {
+ var t = "";
+ for (var i in _jmol.params)
+	if(_jmol.params[i]!="")
+		 t+="  <param name='"+i+"' value='"+_jmol.params[i]+"' />\n";
+ return t
+}
+
+function _jmolInitCheck() {
+  if (_jmol.initChecked)
+    return;
+  _jmol.initChecked = true;
+  jmolInitialize(defaultdir, defaultjar)
+}
+
+function _jmolCheckBrowser() {
+  with (_jmol) {
+    if (browserChecked)
+      return;
+    browserChecked = true;
+  
+    if (isFullyCompliant)
+      return true;
+
+    if (checkBrowserAction == "redirect")
+      location.href = checkBrowserUrlOrMessage;
+    else if (checkBrowserAction == "popup")
+      _jmolPopup(checkBrowserUrlOrMessage);
+    else {
+      var msg = checkBrowserUrlOrMessage;
+      if (msg == null)
+        msg = "Your web browser is not fully compatible with Jmol\n\n" +
+              "browser: " + browser +
+              "   version: " + browserVersion +
+              "   os: " + os +
+              "   isBrowserCompliant: " + isBrowserCompliant +
+              "   isJavaCompliant: " + isJavaCompliant +
+              "\n\n" + ua;
+      alert(msg);
+    }
+  }
+  return false;
+}
+
+function jmolSetXHTML(id) {
+	_jmol.isXHTML = true
+	_jmol.XhtmlElement = null
+	_jmol.XhtmlAppendChild = false
+	if (id){
+		_jmol.XhtmlElement = document.getElementById(id)
+		_jmol.XhtmlAppendChild = true
+	}
+}
+
+function _jmolDocumentWrite(text) {
+	if (_jmol.currentDocument) {
+		if (_jmol.isXHTML && !_jmol.XhtmlElement) {
+			var s = document.getElementsByTagName("script")
+			_jmol.XhtmlElement = s.item(s.length - 1)
+			_jmol.XhtmlAppendChild = false
+		}
+		if (_jmol.XhtmlElement) {
+			_jmolDomDocumentWrite(text)
+		} else {
+			_jmol.currentDocument.write(text);
+		}
+	}
+	return text;
+}
+
+function _jmolDomDocumentWrite(data) {
+	var pt = 0
+	var Ptr = []
+	Ptr[0] = 0
+	while (Ptr[0] < data.length) {
+		var child = _jmolGetDomElement(data, Ptr)
+		if (!child)break
+		if (_jmol.XhtmlAppendChild)
+			_jmol.XhtmlElement.appendChild(child)
+		else
+			_jmol.XhtmlElement.parentNode.insertBefore(child, _jmol.XhtmlElement); 
+	}
+}
+function _jmolGetDomElement(data, Ptr, closetag, lvel) {
+	var e = document.createElement("span")
+	e.innerHTML = data
+	Ptr[0] = data.length
+	return e
+
+//unnecessary?
+
+	closetag || (closetag = "")
+	lvel || (lvel = 0)
+	var pt0 = Ptr[0]
+	var pt = pt0
+	while (pt < data.length && data.charAt(pt) != "<") pt++
+	if (pt != pt0) {
+		var text = data.substring(pt0, pt)
+		Ptr[0] = pt
+		return document.createTextNode(text)
+	}	
+	pt0 = ++pt
+	var ch
+	while (pt < data.length && "\n\r\t >".indexOf(ch = data.charAt(pt)) < 0) pt++
+	var tagname = data.substring(pt0, pt)
+	var e = (tagname == closetag  || tagname == "/" ? "" 
+		: document.createElementNS ? document.createElementNS('http://www.w3.org/1999/xhtml', tagname)
+		: document.createElement(tagname));
+	if (ch == ">") {
+		Ptr[0] = ++pt
+		return e
+	}
+	while (pt < data.length && (ch = data.charAt(pt)) != ">") {
+		while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++
+		pt0 = pt
+		while (pt < data.length && "\n\r\t =/>".indexOf(ch = data.charAt(pt)) < 0) pt++
+		var attrname = data.substring(pt0, pt).toLowerCase()
+		if (attrname && ch != "=") 
+			e.setAttribute(attrname, "true")
+		while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++
+		if (ch == "/") {
+			Ptr[0] = pt + 2
+			return e
+		} else if (ch == "=") {
+			var quote = data.charAt(++pt)
+			pt0 = ++pt
+			while (pt < data.length && (ch = data.charAt(pt)) != quote) pt++
+			var attrvalue = data.substring(pt0, pt)
+			e.setAttribute(attrname, attrvalue)
+			pt++
+		}
+	}
+	Ptr[0] = ++pt
+	while (Ptr[0] < data.length) {
+		var child = _jmolGetDomElement(data, Ptr, "/" + tagname, lvel+1)
+		if (!child)break
+		e.appendChild(child)
+	}
+	return e
+}
+
+function _jmolPopup(url) {
+  var popup = window.open(url, "JmolPopup",
+                          "left=150,top=150,height=400,width=600," +
+                          "directories=yes,location=yes,menubar=yes," +
+                          "toolbar=yes," +
+                          "resizable=yes,scrollbars=yes,status=yes");
+  if (popup.focus)
+    poup.focus();
+}
+
+function _jmolReadyCallback(name) {
+  if (_jmol.debugAlert)
+    alert(name + " is ready");
+  _jmol.ready["" + name] = true;
+}
+
+function _jmolSterilizeScript(script) {
+  script = script.replace(/'/g, "&#39;");
+  if (_jmol.debugAlert)
+    alert("script:\n" + script);
+  return script;
+}
+
+function _jmolSterilizeInline(model) {
+  model = model.replace(/\r|\n|\r\n/g, (model.indexOf("|") >= 0 ? "\\/n" : "|")).replace(/'/g, "&#39;");
+  if (_jmol.debugAlert)
+    alert("inline model:\n" + model);
+  return model;
+}
+
+function _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
+  ++_jmol.radioCount;
+  groupName != undefined && groupName != null || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));
+  if (!script)
+    return "";
+  labelHtml != undefined && labelHtml != null || (labelHtml = script.substring(0, 32));
+  separatorHtml || (separatorHtml = "")
+  var scriptIndex = _jmolAddScript(script);
+  var eospan = "</span>"
+  var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='" 
+	+ groupName + "' id='"+id+"' type='radio' onclick='_jmolClick(this," +
+         scriptIndex + _jmol.targetText + ");return true;' onmouseover='_jmolMouseOver(" +
+         scriptIndex + ");return true;' onmouseout='_jmolMouseOut()' " +
+	 (isChecked ? "checked='true' " : "") + _jmol.radioCssText + " />"
+  if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
+	t += eospan
+	eospan = "";
+  }
+  t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan + separatorHtml;
+
+  return t;
+}
+
+function _jmolFindApplet(target) {
+  // first look for the target in the current window
+  var applet = _jmolFindAppletInWindow(_jmol.appletWindow != null ? _jmol.appletWindow : window, target);
+  // THEN look for the target in child frames
+  if (applet == undefined)
+    applet = _jmolSearchFrames(window, target);
+  // FINALLY look for the target in sibling frames
+  if (applet == undefined)
+    applet = _jmolSearchFrames(top, target); // look starting in top frame
+  return applet;
+}
+
+function _jmolGetApplet(targetSuffix){
+ var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");
+ var applet = _jmolFindApplet(target);
+ if (applet) return applet
+ _jmol.alerted || alert("could not find applet " + target);
+ _jmol.alerted = true;
+ return null
+}
+
+function _jmolSearchFrames(win, target) {
+  var applet;
+  var frames = win.frames;
+  if (frames && frames.length) { // look in all the frames below this window
+   try{
+    for (var i = 0; i < frames.length; ++i) {
+      applet = _jmolSearchFrames(frames[i], target);
+      if (applet)
+        return applet;
+    }
+   }catch(e) {
+	if (_jmol.debugAlert)
+		alert("Jmol.js _jmolSearchFrames cannot access " + win.name + ".frame[" + i + "] consider using jmolSetAppletWindow()") 
+   }
+  }
+  return applet = _jmolFindAppletInWindow(win, target)
+}
+
+function _jmolFindAppletInWindow(win, target) {
+    var doc = win.document;
+		if (doc.getElementById(target))
+      return doc.getElementById(target);
+    else if (doc.applets)
+      return doc.applets[target];
+    else
+      return doc[target]; 
+}
+
+function _jmolAddScript(script) {
+  if (!script)
+    return 0;
+  var index = _jmol.scripts.length;
+  _jmol.scripts[index] = script;
+  return index;
+}
+
+function _jmolClick(elementClicked, scriptIndex, targetSuffix) {
+  _jmol.element = elementClicked;
+  _jmolScriptExecute(elementClicked, _jmol.scripts[scriptIndex], targetSuffix);
+}
+
+function _jmolMenuSelected(menuObject, targetSuffix) {
+  var scriptIndex = menuObject.value;
+  if (scriptIndex != undefined) {
+    _jmolScriptExecute(menuObject, _jmol.scripts[scriptIndex], targetSuffix);
+    return;
+  }
+  var len = menuObject.length;
+  if (typeof len == "number") {
+    for (var i = 0; i < len; ++i) {
+      if (menuObject[i].selected) {
+        _jmolClick(menuObject[i], menuObject[i].value, targetSuffix);
+	return;
+      }
+    }
+  }
+  alert("?Que? menu selected bug #8734");
+}
+
+
+_jmol.checkboxMasters = {};
+_jmol.checkboxItems = {};
+
+function jmolSetCheckboxGroup(chkMaster,chkBox) {
+	var id = chkMaster;
+	if(typeof(id)=="number")id = "jmolCheckbox" + id;
+	chkMaster = document.getElementById(id);
+	if (!chkMaster)alert("jmolSetCheckboxGroup: master checkbox not found: " + id);
+	var m = _jmol.checkboxMasters[id] = {};
+	m.chkMaster = chkMaster;
+	m.chkGroup = {};
+	for (var i = 1; i < arguments.length; i++){
+		var id = arguments[i];
+		if(typeof(id)=="number")id = "jmolCheckbox" + id;
+		checkboxItem = document.getElementById(id);
+		if (!checkboxItem)alert("jmolSetCheckboxGroup: group checkbox not found: " + id);
+		m.chkGroup[id] = checkboxItem;
+		_jmol.checkboxItems[id] = m;
+	}
+}
+
+function _jmolNotifyMaster(m){
+	//called when a group item is checked
+	var allOn = true;
+	var allOff = true;
+	for (var chkBox in m.chkGroup){
+		if(m.chkGroup[chkBox].checked)
+			allOff = false;
+		else
+			allOn = false;
+	}
+	if (allOn)m.chkMaster.checked = true;	
+	if (allOff)m.chkMaster.checked = false;
+	if ((allOn || allOff) && _jmol.checkboxItems[m.chkMaster.id])
+		_jmolNotifyMaster(_jmol.checkboxItems[m.chkMaster.id])
+}
+
+function _jmolNotifyGroup(m, isOn){
+	//called when a master item is checked
+	for (var chkBox in m.chkGroup){
+		var item = m.chkGroup[chkBox]
+		item.checked = isOn;
+		if (_jmol.checkboxMasters[item.id])
+			_jmolNotifyGroup(_jmol.checkboxMasters[item.id], isOn)
+	}
+}
+
+function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) {
+  _jmol.control = ckbox
+  _jmolClick(ckbox, ckbox.checked ? whenChecked : whenUnchecked, targetSuffix);
+  if(_jmol.checkboxMasters[ckbox.id])
+	_jmolNotifyGroup(_jmol.checkboxMasters[ckbox.id], ckbox.checked)
+  if(_jmol.checkboxItems[ckbox.id])
+	_jmolNotifyMaster(_jmol.checkboxItems[ckbox.id])
+}
+
+function _jmolCbOver(ckbox, whenChecked, whenUnchecked) {
+  window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked];
+}
+
+function _jmolMouseOver(scriptIndex) {
+  window.status = _jmol.scripts[scriptIndex];
+}
+
+function _jmolMouseOut() {
+  window.status = " ";
+  return true;
+}
+
+function _jmolSetCodebase(codebase) {
+  _jmol.codebase = codebase ? codebase : ".";
+  if (_jmol.debugAlert)
+    alert("jmolCodebase=" + _jmol.codebase);
+}
+
+function _jmolOnloadResetForms() {
+  // must be evaluated ONLY once
+  _jmol.previousOnloadHandler = window.onload;
+  window.onload =
+  function() {
+    with (_jmol) {
+      if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) {
+        var forms = document.forms;
+        for (var i = forms.length; --i >= 0; )
+          forms[i].reset();
+      }
+      if (previousOnloadHandler)
+        previousOnloadHandler();
+    }
+  }
+}
+
+////////////////////////////////////
+/////extensions for getProperty/////
+////////////////////////////////////
+
+
+function _jmolEvalJSON(s,key){
+ s=s+""
+ if(!s)return []
+ if(s.charAt(0)!="{"){
+	if(s.indexOf(" | ")>=0)s=s.replace(/\ \|\ /g, "\n")
+	return s
+ }
+ var A = eval("("+s+")")
+ if(!A)return
+ if(key && A[key])A=A[key]
+ return A
+}
+
+function _jmolEnumerateObject(A,key){
+ var sout=""
+ if(typeof(A) == "string" && A!="null"){
+	sout+="\n"+key+"=\""+A+"\""
+ }else if(!isNaN(A)||A==null){
+	sout+="\n"+key+"="+(A+""==""?"null":A)
+ }else if(A.length){
+    sout+=key+"=[]"
+    for(var i=0;i<A.length;i++){
+	sout+="\n"
+	if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
+		sout+=_jmolEnumerateObject(A[i],key+"["+i+"]")
+	}else{
+		sout+=key+"["+i+"]="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
+	}
+    }
+ }else{
+    if(key != ""){
+	sout+=key+"={}"
+	key+="."
+    }
+    
+    for(var i in A){
+	sout+="\n"
+	if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
+		sout+=_jmolEnumerateObject(A[i],key+i)
+	}else{
+		sout+=key+i+"="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
+	}
+    }
+ } 
+ return sout
+}
+
+
+function _jmolSortKey0(a,b){
+ return (a[0]<b[0]?1:a[0]>b[0]?-1:0)
+}
+
+function _jmolSortMessages(A){
+ if(!A || typeof(A)!="object")return []
+ var B = []
+ for(var i=A.length-1;i>=0;i--)for(var j=0;j<A[i].length;j++)B[B.length]=A[i][j]
+ if(B.length == 0) return
+ B=B.sort(_jmolSortKey0)
+ return B
+}
+
+/////////additional extensions //////////
+
+
+function _jmolDomScriptLoad(URL){
+ //open(URL) //to debug
+ _jmol.servercall=URL
+ var node = document.getElementById("_jmolScriptNode")
+ if (node && _jmol.browser!="msie"){
+    document.getElementsByTagName("HEAD")[0].removeChild(node)
+    node=null
+ }
+ if (node) {
+   node.setAttribute("src",URL)
+ } else {
+   node=document.createElement("script")
+   node.setAttribute("id","_jmolScriptNode")
+   node.setAttribute("type","text/javascript")
+   node.setAttribute("src",URL)
+   document.getElementsByTagName("HEAD")[0].appendChild(node)
+ }
+}
+
+
+function _jmolExtractPostData(url){
+ S=url.split("&POST:")
+ var s=""
+ for(var i=1;i<S.length;i++){
+	KV=S[i].split("=")
+	s+="&POSTKEY"+i+"="+KV[0]
+	s+="&POSTVALUE"+i+"="+KV[1]
+ }
+ return "&url="+escape(S[0])+s
+}
+
+function _jmolLoadModel(targetSuffix,remoteURL,array,isError,errorMessage){
+ //called by server, but in client
+ //overload this function to customize return
+ _jmol.remoteURL=remoteURL
+ isError && alert(errorMessage)
+ jmolLoadInlineScript(array.join("\n"),_jmol.optionalscript,targetSuffix)
+}
+
+//////////user property/status functions/////////
+
+function jmolGetStatus(strStatus,targetSuffix){
+ return _jmolSortMessages(jmolGetPropertyAsArray("jmolStatus",strStatus,targetSuffix))
+}
+
+function jmolGetPropertyAsArray(sKey,sValue,targetSuffix) {
+ return _jmolEvalJSON(jmolGetPropertyAsJSON(sKey,sValue,targetSuffix),sKey)
+}
+
+function jmolGetPropertyAsString(sKey,sValue,targetSuffix) {
+ var applet = _jmolGetApplet(targetSuffix);
+ sValue == undefined && (sValue="");
+ return (applet ? applet.getPropertyAsString(sKey,sValue) + "" : "")
+}
+
+function jmolGetPropertyAsJSON(sKey,sValue,targetSuffix) {
+ sValue == undefined && (sValue = "")
+ var applet = _jmolGetApplet(targetSuffix);
+ try {
+  return (applet ? applet.getPropertyAsJSON(sKey,sValue) + "" : "")
+ } catch(e) {
+  return ""
+ }
+}
+
+function jmolGetPropertyAsJavaObject(sKey,sValue,targetSuffix) {
+ sValue == undefined && (sValue = "")
+ var applet = _jmolGetApplet(targetSuffix);
+ return (applet ? applet.getProperty(sKey,sValue) : null)
+}
+
+
+function jmolDecodeJSON(s) {
+ return _jmolEnumerateObject(_jmolEvalJSON(s),"")
+}
+
+
+///////// synchronous scripting ////////
+
+function jmolScriptWait(script, targetSuffix) {
+  targetSuffix == undefined && (targetSuffix="0")
+  var Ret=jmolScriptWaitAsArray(script, targetSuffix)
+  var s = ""
+  for(var i=Ret.length;--i>=0;)
+  for(var j=0;j< Ret[i].length;j++)
+	s+=Ret[i][j]+"\n"
+  return s
+}
+
+function jmolScriptWaitOutput(script, targetSuffix) {
+  targetSuffix == undefined && (targetSuffix="0")
+  var ret = ""
+  try{
+   if (script) {
+    _jmolCheckBrowser();
+    var applet=_jmolGetApplet(targetSuffix);
+    if (applet) ret += applet.scriptWaitOutput(script);
+   }
+  }catch(e){
+  }
+ return ret;
+}
+
+function jmolEvaluate(molecularMath, targetSuffix) {
+
+  //carries out molecular math on a model
+
+  targetSuffix == undefined && (targetSuffix="0")
+  var result = "" + jmolGetPropertyAsJavaObject("evaluate", molecularMath, targetSuffix);
+  var s = result.replace(/\-*\d+/,"")
+  if (s == "" && !isNaN(parseInt(result)))return parseInt(result);
+  var s = result.replace(/\-*\d*\.\d*/,"")
+  if (s == "" && !isNaN(parseFloat(result)))return parseFloat(result);
+  return result;
+}
+
+function jmolScriptEcho(script, targetSuffix) {
+  // returns a newline-separated list of all echos from a script
+  targetSuffix == undefined && (targetSuffix="0")
+  var Ret=jmolScriptWaitAsArray(script, targetSuffix)
+  var s = ""
+  for(var i=Ret.length;--i>=0;)
+  for(var j=Ret[i].length;--j>=0;)
+        if (Ret[i][j][1] == "scriptEcho")s+=Ret[i][j][3]+"\n"
+  return s.replace(/ \| /g, "\n")
+}
+
+
+function jmolScriptMessage(script, targetSuffix) {
+  // returns a newline-separated list of all messages from a script, ending with "script completed\n"
+  targetSuffix == undefined && (targetSuffix="0")
+  var Ret=jmolScriptWaitAsArray(script, targetSuffix)
+  var s = ""
+  for(var i=Ret.length;--i>=0;)
+  for(var j=Ret[i].length;--j>=0;)
+        if (Ret[i][j][1] == "scriptStatus")s+=Ret[i][j][3]+"\n"
+  return s.replace(/ \| /g, "\n")
+}
+
+
+function jmolScriptWaitAsArray(script, targetSuffix) {
+ var ret = ""
+ try{
+  jmolGetStatus("scriptEcho,scriptMessage,scriptStatus,scriptError",targetSuffix)
+  if (script) {
+    _jmolCheckBrowser();
+    var applet=_jmolGetApplet(targetSuffix);
+    if (applet) ret += applet.scriptWait(script);
+    ret = _jmolEvalJSON(ret,"jmolStatus")
+    if(typeof ret == "object")
+	return ret
+  }
+ }catch(e){
+ }
+  return [[ret]]
+}
+
+
+
+////////////   save/restore orientation   /////////////
+
+function jmolSaveOrientation(id, targetSuffix) {  
+ targetSuffix == undefined && (targetSuffix="0")
+ return _jmol["savedOrientation"+id] = jmolGetPropertyAsArray("orientationInfo","info",targetSuffix).moveTo
+}
+
+function jmolRestoreOrientation(id, targetSuffix) {
+ targetSuffix == undefined && (targetSuffix="0")
+ var s=_jmol["savedOrientation"+id]
+ if (!s || s == "")return
+ s=s.replace(/1\.0/,"0")
+ return jmolScriptWait(s,targetSuffix)
+}
+
+function jmolRestoreOrientationDelayed(id, delay, targetSuffix) {
+ arguments.length < 2 && (delay=1)
+ targetSuffix == undefined && (targetSuffix="0")
+ var s=_jmol["savedOrientation"+id]
+ if (!s || s == "")return
+ s=s.replace(/1\.0/,delay)
+ return jmolScriptWait(s,targetSuffix)
+}
+
+////////////  add parameter /////////////
+/*
+ * for adding callbacks or other parameters. Use:
+
+   jmolSetDocument(0)
+   var s= jmolApplet(....)
+   s = jmolAppletAddParam(s,"messageCallback", "myFunctionName")
+   document.write(s)
+   jmolSetDocument(document) // if you want to then write buttons and such normally
+ 
+ */
+
+function jmolAppletAddParam(appletCode,name,value){
+  return (value == "" ? appletCode : appletCode.replace(/\<param/,"\n<param name='"+name+"' value='"+value+"' />\n<param"))
+}
+
+///////////////auto load Research Consortium for Structural Biology (RCSB) data ///////////
+
+function jmolLoadAjax_STOLAF_RCSB(fileformat,pdbid,optionalscript,targetSuffix){
+
+ _jmol.thismodel || (_jmol.thismodel = "1crn")
+ _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")
+ _jmol.RCSBserver || (_jmol.RCSBserver="http://www.rcsb.org")
+ _jmol.defaultURL_RCSB || (_jmol.defaultURL_RCSB=_jmol.RCSBserver+"/pdb/files/1CRN.CIF")
+ fileformat || (fileformat="PDB")
+ pdbid || (pdbid=prompt("Enter a 4-digit PDB ID:",_jmol.thismodel))
+ if(!pdbid || pdbid.length != 4)return ""
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ var url=_jmol.defaultURL_RCSB.replace(/1CRN/g,pdbid.toUpperCase())
+ fileformat=="CIF" || (url=url.replace(/CIF/,fileformat))
+ _jmol.optionalscript=optionalscript
+ _jmol.thismodel=pdbid
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.thisurl=url
+ _jmol.modelArray = []
+ url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
+ _jmolDomScriptLoad(url)
+ return url
+}
+
+/////////////// St. Olaf College AJAX server -- ANY URL ///////////
+
+function jmolLoadAjax_STOLAF_ANY(url, userid, optionalscript,targetSuffix){
+ _jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm"
+ _jmol.thisurlANY || (_jmol.thisurlANY = "http://www.stolaf.edu/depts/chemistry/mo/struc/data/ycp3-1.mol")
+ url || (url=prompt("Enter any (uncompressed file) URL:", _jmol.thisurlANY))
+ userid || (userid="0")
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ _jmol.optionalscript=optionalscript
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.modelArray = []
+ _jmol.thisurl = url
+ url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
+ _jmolDomScriptLoad(url)
+}
+
+
+/////////////// Mineralogical Society of America (MSA) data /////////
+
+function jmolLoadAjax_MSA(key,value,optionalscript,targetSuffix){
+
+ _jmol.thiskeyMSA || (_jmol.thiskeyMSA = "mineral")
+ _jmol.thismodelMSA || (_jmol.thismodelMSA = "quartz")
+ _jmol.ajaxURL_MSA || (_jmol.ajaxURL_MSA="http://rruff.geo.arizona.edu/AMS/result.php?mineral=quartz&viewing=ajaxjs")
+ key || (key=prompt("Enter a field:", _jmol.thiskeyMSA))
+ if(!key)return ""
+ value || (value=prompt("Enter a "+key+":", _jmol.thismodelMSA))
+ if(!value)return ""
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ optionalscript == 1 && (optionalscript='load "" {1 1 1}')
+ var url=_jmol.ajaxURL_MSA.replace(/mineral/g,key).replace(/quartz/g,value)
+ _jmol.optionalscript=optionalscript
+ _jmol.thiskeyMSA=key
+ _jmol.thismodelMSA=value
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.thisurl=url
+ _jmol.modelArray = []
+ loadModel=_jmolLoadModel
+ _jmolDomScriptLoad(url)
+ return url
+}
+
+
+
+function jmolLoadAjaxJS(url, userid, optionalscript,targetSuffix){
+ userid || (userid="0")
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ _jmol.optionalscript=optionalscript
+ _jmol.thismodel=userid
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.modelArray = []
+ _jmol.thisurl = url
+ url+="&returnFunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix
+ _jmolDomScriptLoad(url)
+}
+
+
+//// in case Jmol library has already been loaded:
+
+}catch(e){}
+
+///////////////moving atoms //////////////
+
+// HIGHLY experimental!!
+
+function jmolSetAtomCoord(i,x,y,z,targetSuffix){
+    _jmolCheckBrowser();
+      var applet=_jmolGetApplet(targetSuffix);
+      if (applet) applet.getProperty('jmolViewer').setAtomCoord(i,x,y,z)
+}
+
+function jmolSetAtomCoordRelative(i,x,y,z,targetSuffix){
+    _jmolCheckBrowser();
+      var applet=_jmolGetApplet(targetSuffix);
+      if (applet) applet.getProperty('jmolViewer').setAtomCoordRelative(i,x,y,z)
+}
+
+
+///////////////applet fake for testing buttons/////////////
+
+
+if(_jmol.useNoApplet){
+	jmolApplet = function(w){
+		var s="<table style='background-color:black' width="+w+"><tr height="+w+">"
+		+"<td align=center valign=center style='background-color:white'>"
+		+"Applet would be here"
+		+"<p><textarea id=fakeApplet rows=5 cols=50></textarea>"
+		+"</td></tr></table>"
+		return _jmolDocumentWrite(s)
+	}
+
+	_jmolFindApplet = function(){return jmolApplet0}
+
+	jmolApplet0 = {
+	 script: function(script){document.getElementById("fakeApplet").value="\njmolScript:\n"+script}
+	,scriptWait: function(script){document.getElementById("fakeApplet").value="\njmolScriptWait:\n"+script}	
+	,loadInline: function(data,script){document.getElementById("fakeApplet").value="\njmolLoadInline data:\n"+data+"\n\nscript:\n"+script}
+	}
+}
+
+
+///////////////////////////////////////////
+
+  //  This should no longer be needed, jmolResizeApplet() is better; kept for backwards compatibility
+  /*
+	Resizes absolutely (pixels) or by percent of window (w or h 0.5 means 50%).
+	targetSuffix is optional and defaults to zero (first applet in page).
+	Both w and h are optional, but needed if you want to use targetSuffix.
+		h defaults to w
+		w defaults to 100% of window
+	If either w or h is between 0 and 1, then it is taken as percent/100.
+	If either w or h is greater than 1, then it is taken as a size (pixels). 
+	*/
+function jmolResize(w,h,targetSuffix) {
+ _jmol.alerted = true;
+ var percentW = (!w ? 100 : w <= 1  && w > 0 ? w * 100 : 0);
+ var percentH = (!h ? percentW : h <= 1 && h > 0 ? h * 100 : 0);
+ if (_jmol.browser=="msie") {
+   var width=document.body.clientWidth;
+   var height=document.body.clientHeight;
+ } else {
+   var netscapeScrollWidth=15;
+   var width=window.innerWidth - netscapeScrollWidth;
+   var height=window.innerHeight-netscapeScrollWidth;
+ }
+ var applet = _jmolGetApplet(targetSuffix);
+ if(!applet)return;
+ applet.style.width = (percentW ? width * percentW/100 : w)+"px";
+ applet.style.height = (percentH ? height * percentH/100 : (h ? h : w))+"px";
+ //title=width +  " " + height + " " + (new Date());
+}
+
+// 13 Jun 09 -- makes jmolResize() obsolete  (kept for backwards compatibility)
+function jmolResizeApplet(size,targetSuffix) {
+ // See _jmolGetAppletSize() for the formats accepted as size [same used by jmolApplet()]
+ //  Special case: an empty value for width or height is accepted, meaning no change in that dimension.
+ _jmol.alerted = true;
+ var applet = _jmolGetApplet(targetSuffix);
+ if(!applet)return;
+ var sz = _jmolGetAppletSize(size, "px");
+ sz[0] && (applet.style.width = sz[0]);
+ sz[1] && (applet.style.height = sz[1]);
+}
+
+function _jmolGetAppletSize(size, units) {
+	/* Accepts single number or 2-value array, each one can be one of:
+	   percent (text string ending %), decimal 0 to 1 (percent/100), number, or text string (interpreted as nr.)
+	   [width, height] array of strings is returned, with units added if specified.
+	   Percent is relative to container div or element (which should have explicitly set size).
+	*/
+  var width, height;
+  if ( (typeof size) == "object" && size != null ) {
+    width = size[0]; height = size[1];
+  } else {
+    width = height = size;
+  }
+  return [_jmolFixDim(width, units), _jmolFixDim(height, units)];
+}
+
+function _jmolFixDim(x, units) {
+  var sx = "" + x;
+  return (sx.length == 0 ? (units ? "" : _jmol.allowedJmolSize[2])
+	: sx.indexOf("%") == sx.length-1 ? sx 
+  	: (x = parseFloat(x)) <= 1 && x > 0 ? x * 100 + "%"
+  	: (isNaN(x = Math.floor(x)) ? _jmol.allowedJmolSize[2]
+  		: x < _jmol.allowedJmolSize[0] ? _jmol.allowedJmolSize[0]
+  	    : x > _jmol.allowedJmolSize[1] ? _jmol.allowedJmolSize[1] 
+        : x) + (units ? units : ""));
+}
+
+
+
+
diff --git a/JmolHelp.html b/JmolHelp.html
new file mode 100644
index 0000000..16bc59e
--- /dev/null
+++ b/JmolHelp.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html><head>
+
+
+
+
+  <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>JmolHelp</title>
+  
+  <meta content="J. Gutow" name="author">
+  <meta content="Brief Jmol instructions for SAGE math" name="description"></head><body>
+<div style="text-align: center;">
+<h3>Brief Help for the Jmol 3-D viewer</h3>
+<div style="text-align: left;">
+<dl>
+  <dt>Reorient View</dt>
+  <dd>To reorient the view&nbsp;place cursor over the image, hold down
+the mouse button and drag.</dd>
+  <dt>Zoom View</dt>
+  <dd>To
+zoom place the cursor over the image hold down the shift key and the
+mouse button while dragging down to zoom in or up to zoom out.</dd><dt>Change Applet Size</dt>
+  <dd>Select the desired size from the pop-up menu in the "Display" tab
+available in the "Advanced Controls" or click on the "Open in own
+window" button.&nbsp; The resulting window's size can be adjusted.<br>
+  </dd>
+  <dt>Adjust Colors and Mesh</dt>
+  <dd>Select desired colors and translucency using the menus and
+checkboxes in the "Colors &amp; Mesh" tab available in the "Advanced
+Controls".<br>
+  </dd>
+  <dt>Save as Static Image</dt>
+  <dd>Click on the "Get Static Image to Save" button in the "Display" tab available in the "Advanced Controls".<br>
+  </dd>
+  <dt>Download to open in Jmol Application</dt>
+  <dd>Click on the "Download View" button in the "Display" tab
+available in the "Advanced Controls".&nbsp; The file you download can
+be opened using the Jmol application.&nbsp; Using the application the
+view can be further adjusted and web pages with the live view embedded
+can be created (<a href="#Embedding">see below</a>).<br>
+  </dd>
+  <dt>Start/Stop Spinning</dt>
+  <dd>Use the "Spin" checkbox in the "Display" tab available in the "Advanced Controls".</dd>
+  <dt>High/Low Quality Display</dt>
+  <dd>Use the "High Quality" checkbox in the "Display" tab available in
+the "Advanced Controls".&nbsp; Note memory requirements are
+significantly more for the better display.&nbsp; This can slow the
+applets response and sometimes causes blank displays.</dd><dt><br>
+  </dt>
+
+
+  <dt><a name="Embedding"></a>Embedding the live image in another web page, adding annotation
+and advanced control of view<br>
+  </dt>
+</dl>
+<ol>
+  <li>Download the view to your computer using the download button in
+the Display tab.&nbsp; You can then open the file in the Jmol
+application available from the <a href="http://www.jmol.org/">Jmol web
+site</a>.&nbsp;</li>
+  <li>Simple examples of adding annotation are provided in the <a href="http://www.uwosh.edu/faculty_staff/gutow/Jmol_Web_Page_Maker/Export_to_web_tutorial.shtml">Export-to-Web
+tutorial</a>, which also describes how to use the downloaded document to
+embed the live image in an arbitrary web page.</li>
+  <li>More detailed information on changing the way Jmol displays
+things using Jmol commands is available in the <a href="http://chemapps.stolaf.edu/jmol/docs/"><span style="text-decoration: underline;">J</span></a><a href="http://chemapps.stolaf.edu/jmol/docs/">mol scripting
+documentation</a>, the <a href="http://www.jmol.org/">Jmol web site</a>
+and the <a href="http://wiki.jmol.org/">Jmol wiki</a>.</li>
+  <li>It is also possible to use Jmol commands to adjust the display
+within Sage.&nbsp; To do this
+right-click (control-click) in the applet window to get the applet
+pop-up menu. &nbsp;In the advanced submenu select "Console". &nbsp;You
+can type Jmol script commands into the console.</li>
+</ol>
+<div style="text-align: right;"><small><small>By Jonathan Gutow<br>
+June 2011<br>
+</small></small></div>
+</div>
+</div>
+
+</body></html>
\ No newline at end of file
diff --git a/gprc.expect b/gprc.expect
new file mode 100644
index 0000000..95122d9
--- /dev/null
+++ b/gprc.expect
@@ -0,0 +1,11 @@
+compatible = 0
+
+/* gp prompt */
+prompt = "? "
+
+/* Disable timer */
+timer = 0
+
+/* Disable the break loop, otherwise gp will seem to hang on errors */
+breakloop = 0
+
diff --git a/makecmds.sty b/makecmds.sty
new file mode 100644
index 0000000..7805257
--- /dev/null
+++ b/makecmds.sty
@@ -0,0 +1,95 @@
+%%
+%% This is file `makecmds.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% makecmds.dtx  (with options: `usc')
+%% 
+%%  Copyright 2000 Peter R. Wilson
+%% 
+%%  This program is provided under the terms of the
+%%  LaTeX Project Public License distributed from CTAN
+%%  archives in directory macros/latex/base/lppl.txt.
+%% 
+%% Author: Peter Wilson (CUA)
+%%         now at: peter.r.wilson at boeing.com
+%% 
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{makecmds}[2000/05/27 v1.0 extra command making commands]
+
+\newif\ifm at kwarn
+  \m at kwarnfalse
+\DeclareOption{warn}{\m at kwarntrue}
+\ProcessOptions\relax
+
+\def\makecommand{\@star at or@long\m at ke@command}
+\def\m at ke@command#1{%
+  \ifx #1\undefined\else
+    \ifm at kwarn
+      \PackageWarning{makecmds}{Redefining command `\protect#1'}
+    \fi
+  \fi
+  \let\@ifdefinable\@rc at ifdefinable
+  \new at command#1}
+
+\def\provideenvironment{%
+  \@star at or@long\m at kprovide@environment}
+\def\m at kprovide@environment#1{%
+  \@ifundefined{#1}{%
+    \expandafter\let\csname#1\endcsname\relax
+    \expandafter\let\csname end#1\endcsname\relax
+    \new at environment{#1}}{\m at kdiscardenvargs{#1}}
+}
+\def\m at kdiscardenvargs#1{%
+  \@testopt{\m at kenva#1}0}
+\def\m at kenva#1[#2]{%
+  \@ifnextchar [{\m at kenvb#1[#2]}{\m at kthrowenv{#1}{[#2]}}}
+\def\m at kenvb#1[#2][#3]{\m at kthrowenv{#1}{[#2][#3]}}
+\def\m at kthrowenv#1#2#3#4{}
+
+\def\makeenvironment{\@star at or@long\m at ke@environment}
+\def\m at ke@environment#1{%
+  \@ifundefined{#1}{\new at environment{#1}}{%
+    \ifm at kwarn
+      \PackageWarning{makecmds}{Redefining environment `#1'}
+    \fi
+    \renew at environment{#1}}
+}
+
+\def\providelength#1{%
+  \ifx #1\undefined
+    \newlength{#1}
+  \fi
+}
+\def\makelength#1{%
+  \ifx #1\undefined
+    \newlength{#1}
+  \else
+    \ifm at kwarn
+      \PackageWarning{makecmds}{Redefining length `\protect#1'}
+    \fi
+    \newskip#1
+  \fi
+}
+
+\def\providecounter#1{%
+  \@ifundefined{c@#1}{\newcounter{#1}}{%
+    \@ifnextchar[{\m at k@gobbleendoptarg}{}}%
+}
+\def\makecounter#1{%
+  \expandafter\ifx \csname c@#1\endcsname \undefined
+  \else
+    \ifm at kwarn
+      \PackageWarning{makecmds}{Redefining counter `#1'}
+    \fi
+  \fi
+  \@definecounter{#1}%
+  \@ifnextchar[{\@newctr{#1}}{}
+}
+
+\def\m at k@gobbleendoptarg[#1]{}
+
+\endinput
+%%
+%% End of file `makecmds.sty'.
diff --git a/sagemath-4ti2.patch b/sagemath-4ti2.patch
new file mode 100644
index 0000000..23f660a
--- /dev/null
+++ b/sagemath-4ti2.patch
@@ -0,0 +1,22 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/sandpiles/sandpile.py.orig sage-5.8/spkg/build/sage-5.8/sage/sandpiles/sandpile.py
+--- sage-5.8/spkg/build/sage-5.8/sage/sandpiles/sandpile.py.orig	2012-07-11 14:39:38.474386100 -0400
++++ sage-5.8/spkg/build/sage-5.8/sage/sandpiles/sandpile.py	2012-07-11 14:40:33.870388225 -0400
+@@ -22,9 +22,6 @@ http://sagemath.org/download-packages.ht
+ packages.  An alternative is to install 4ti2 separately, then point the
+ following variable to the correct path.
+ """
+-SAGE_ROOT = os.environ['SAGE_ROOT']
+-path_to_zsolve = SAGE_ROOT+'/local/bin/'
+-
+ r"""
+ Sage Sandpiles
+ 
+@@ -4097,7 +4094,7 @@ class SandpileDivisor(dict):
+         sign_file.close()
+         # compute
+         try:
+-            os.system(path_to_zsolve+'zsolve -q ' + lin_sys + ' > ' + lin_sys_log)
++            os.system('zsolve -q ' + lin_sys + ' > ' + lin_sys_log)
+             # process the results
+             zhom_file = open(lin_sys_zhom,'r')
+         except IOError:
diff --git a/sagemath-buildroot.patch b/sagemath-buildroot.patch
new file mode 100644
index 0000000..379e2c9
--- /dev/null
+++ b/sagemath-buildroot.patch
@@ -0,0 +1,23 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+--- sage-5.8/spkg/build/sage-5.8/module_list.py.orig	2013-03-19 16:03:38.039687555 -0300
++++ sage-5.8/spkg/build/sage-5.8/module_list.py	2013-03-19 16:03:47.215687907 -0300
+@@ -16,7 +16,7 @@ else:
+     SAGE_ROOT  = os.environ['SAGE_ROOT']
+     SAGE_LOCAL = SAGE_ROOT + '/local'
+     SAGE_DEVEL = SAGE_ROOT + '/devel'
+-    SAGE_INC = SAGE_LOCAL + '/include/'
++    SAGE_INC = '/usr/include/'
+ 
+ 
+ #########################################################
+@@ -1697,8 +1697,8 @@ ext_modules = [
+               sources = ['sage/rings/polynomial/plural.pyx'],
+               libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'],
+               language="c++",
+-              include_dirs = [SAGE_ROOT +'/local/include/singular'],
+-              depends = [SAGE_ROOT + "/local/include/libsingular.h"],
++              include_dirs = [SAGE_INC + 'singular', SAGE_INC + 'factory'],
++              depends = singular_depends,
+               extra_compile_args = givaro_extra_compile_args),
+ 
+     Extension('sage.rings.polynomial.multi_polynomial_libsingular',
diff --git a/sagemath-cbc.patch b/sagemath-cbc.patch
new file mode 100644
index 0000000..2421382
--- /dev/null
+++ b/sagemath-cbc.patch
@@ -0,0 +1,122 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+--- sage-5.8/spkg/build/sage-5.8/module_list.py.orig	2013-03-19 18:12:56.762984664 -0300
++++ sage-5.8/spkg/build/sage-5.8/module_list.py	2013-03-19 18:13:07.073985059 -0300
+@@ -2029,7 +2029,7 @@ if (os.path.isfile(SAGE_INC + "cplex.h")
+                   libraries = ["csage", "stdc++", "cplex"]) 
+         )
+ 
+-if is_package_installed('cbc'):
++if 1:
+     ext_modules.append(
+         Extension("sage.numerical.backends.coin_backend",                                                                                                                                                                                     
+                   ["sage/numerical/backends/coin_backend.pyx"],
+diff -up sage-5.8/spkg/build/sage-5.8/sage/numerical/backends/coin_backend.pxd.orig sage-5.8/spkg/build/sage-5.8/sage/numerical/backends/coin_backend.pxd
+--- sage-5.8/spkg/build/sage-5.8/sage/numerical/backends/coin_backend.pxd.orig	2013-03-19 18:12:59.568984771 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/numerical/backends/coin_backend.pxd	2013-03-19 18:13:07.074985059 -0300
+@@ -22,23 +22,23 @@ from libcpp cimport bool
+ cdef extern from *:
+     ctypedef double* const_double_ptr "const double*"
+ 
+-cdef extern from "../../local/include/coin/CbcStrategy.hpp":
++cdef extern from "coin/CbcStrategy.hpp":
+     cdef cppclass CbcStrategy:
+         pass
+     cdef cppclass CbcStrategyDefault(CbcStrategy):
+-        CbcStrategyDefault(int cutsOnlyAtRoot=?, int numberStrong = ?, int numberBeforeTrust = ?, int printLevel = ?)
++        CbcStrategyDefault(int cutsOnlyAtRoot=1, int numberStrong = 5, int numberBeforeTrust = 0, int printLevel = 0)
+ 
+-cdef extern from "../../local/include/coin/CoinPackedVectorBase.hpp":
++cdef extern from "coin/CoinPackedVectorBase.hpp":
+     cdef cppclass CoinPackedVectorBase:
+         pass
+ 
+-cdef extern from "../../local/include/coin/CoinPackedVector.hpp":
++cdef extern from "coin/CoinPackedVector.hpp":
+      cdef cppclass CoinPackedVector(CoinPackedVectorBase):
+          void insert(float, float)
+      CoinPackedVector *new_CoinPackedVector "new CoinPackedVector" ()
+      void del_CoinPackedVector "delete" (CoinPackedVector *)
+ 
+-cdef extern from "../../local/include/coin/CoinShallowPackedVector.hpp":
++cdef extern from "coin/CoinShallowPackedVector.hpp":
+      cdef cppclass CoinShallowPackedVector:
+          void insert(float, float)
+          int * getIndices ()
+@@ -47,7 +47,7 @@ cdef extern from "../../local/include/co
+      CoinShallowPackedVector *new_CoinShallowPackedVector "new CoinShallowPackedVector" ()
+      void del_CoinShallowPackedVector "delete" (CoinShallowPackedVector *)
+ 
+-cdef extern from "../../local/include/coin/CoinPackedMatrix.hpp":
++cdef extern from "coin/CoinPackedMatrix.hpp":
+      cdef cppclass CoinPackedMatrix:
+          void setDimensions(int, int)
+          void appendRow(CoinPackedVector)
+@@ -55,7 +55,7 @@ cdef extern from "../../local/include/co
+      CoinPackedMatrix *new_CoinPackedMatrix "new CoinPackedMatrix" (bool, double, double)
+      void del_CoinPackedMatrix "delete" (CoinPackedMatrix *)
+ 
+-cdef extern from "../../local/include/coin/CoinMessageHandler.hpp":
++cdef extern from "coin/CoinMessageHandler.hpp":
+      cdef cppclass CoinMessageHandler:
+          void setLogLevel (int)
+          int LogLevel ()
+@@ -63,11 +63,11 @@ cdef extern from "../../local/include/co
+      void del_CoinMessageHandler "delete" (CoinMessageHandler *)
+ 
+ 
+-cdef extern from "../../local/include/coin/OsiSolverParameters.hpp":
++cdef extern from "coin/OsiSolverParameters.hpp":
+     cdef enum OsiIntParam:
+         OsiMaxNumIteration = 0, OsiMaxNumIterationHotStart, OsiNameDiscipline, OsiLastIntParam
+ 
+-cdef extern from "../../local/include/coin/OsiSolverInterface.hpp":
++cdef extern from "coin/OsiSolverInterface.hpp":
+ 
+      cdef cppclass OsiSolverInterface:
+ 
+@@ -130,19 +130,19 @@ cdef extern from "../../local/include/co
+         # miscellaneous
+         double getInfinity()
+ 
+-cdef extern from "../../local/include/coin/CbcModel.hpp":
++cdef extern from "coin/CbcModel.hpp":
+      cdef cppclass CbcModel:
+          # default constructor
+          CbcModel()
+          # constructor from solver
+          CbcModel(OsiSolverInterface & si)
+          # assigning, owning solver
+-         void assignSolver(OsiSolverInterface * & solver, bool deleteSolver=?)
++         void assignSolver(OsiSolverInterface * & solver, bool deleteSolver=true)
+          void setModelOwnsSolver(bool ourSolver)
+          # get solver
+          OsiSolverInterface * solver()
+          # copy constructor
+-         CbcModel(CbcModel & rhs, int cloneHandler = ?)
++         CbcModel(CbcModel & rhs, int cloneHandler = false)
+          # shut up
+          void setLogLevel(int value)
+          int logLevel()
+@@ -152,7 +152,7 @@ cdef extern from "../../local/include/co
+          void setNumberThreads (int)
+          int getSolutionCount()
+          # solve
+-         void branchAndBound(int doStatistics = ?)
++         void branchAndBound(int doStatistics = 0)
+          # not sure we need this but it can't hurt
+          CoinMessageHandler * messageHandler ()
+      void CbcMain0(CbcModel m)
+@@ -160,11 +160,11 @@ cdef extern from "../../local/include/co
+      CbcModel *new_CbcModel "new CbcModel" ()
+      void del_CbcModel "delete" (CbcModel *)
+ 
+-cdef extern from "../../local/include/coin/ClpSimplex.hpp":
++cdef extern from "coin/ClpSimplex.hpp":
+     cdef cppclass ClpSimplex:
+         void setNumberThreads(int)
+ 
+-cdef extern from "../../local/include/coin/OsiClpSolverInterface.hpp":
++cdef extern from "coin/OsiClpSolverInterface.hpp":
+ 
+      cdef cppclass OsiClpSolverInterface(OsiSolverInterface):
+ 
diff --git a/sagemath-cremona.patch b/sagemath-cremona.patch
new file mode 100644
index 0000000..d591723
--- /dev/null
+++ b/sagemath-cremona.patch
@@ -0,0 +1,36 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/databases/cremona.py.orig sage-5.8/spkg/build/sage-5.8/sage/databases/cremona.py
+--- sage-5.8/spkg/build/sage-5.8/sage/databases/cremona.py.orig	2013-02-22 17:33:50.579875129 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/databases/cremona.py	2013-02-22 17:34:05.051875683 -0300
+@@ -889,14 +889,9 @@ class MiniCremonaDatabase(SQLDatabase):
+             if N < self.largest_conductor():
+                 message = "There is no elliptic curve with label " + label \
+                     + " in the database"
+-            elif is_package_installed('database_cremona_ellcurve'):
+-                message = "There is no elliptic curve with label " + label \
+-                    + " in the currently available databases"
+             else:
+                 message = "There is no elliptic curve with label " \
+-                    + label + " in the default database; try installing " \
+-                    + "the optional package database_cremona_ellcurve which " \
+-                    + "contains the complete Cremona database"
++                    + label + " in the default database"
+             raise ValueError(message)
+ 
+     def iter(self, conductors):
+@@ -1594,10 +1589,12 @@ def CremonaDatabase(name=None,mini=None,
+     if name is None and not set_global:
+         return _db
+     if set_global and name is None:
+-        if is_package_installed('database_cremona_ellcurve'):
+-            name = 'cremona'
+-        else:
+-            name = 'cremona mini'
++        # currently the sagemath rpm package only installs cremona mini
++        #if is_package_installed('database_cremona_ellcurve'):
++        #    name = 'cremona'
++        #else:
++        #    name = 'cremona mini'
++        name = 'cremona mini'
+     if name == 'cremona':
+         mini = False
+     elif name == 'cremona mini':
diff --git a/sagemath-cryptominisat.patch b/sagemath-cryptominisat.patch
new file mode 100644
index 0000000..17ddec0
--- /dev/null
+++ b/sagemath-cryptominisat.patch
@@ -0,0 +1,23 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+--- sage-5.8/spkg/build/sage-5.8/module_list.py.orig	2013-03-20 12:35:59.851109864 -0300
++++ sage-5.8/spkg/build/sage-5.8/module_list.py	2013-03-20 12:36:15.993110482 -0300
+@@ -2039,16 +2039,16 @@ if is_package_installed('cbc'):
+         )
+ 
+ 
+-if is_package_installed('cryptominisat'):
++if 1:
+     ext_modules.extend([
+         Extension("sage.sat.solvers.cryptominisat.cryptominisat",
+                   ["sage/sat/solvers/cryptominisat/cryptominisat.pyx"],
+-                  include_dirs = [SAGE_INC, SAGE_INC+"/cmsat"],
++                  include_dirs = [SAGE_INC, SAGE_INC+"cmsat"],
+                   language = "c++",
+                   libraries = ['cryptominisat', 'z']),
+         Extension("sage.sat.solvers.cryptominisat.solverconf",
+                   ["sage/sat/solvers/cryptominisat/solverconf.pyx", "sage/sat/solvers/cryptominisat/solverconf_helper.cpp"],
+-                  include_dirs = [SAGE_INC, SAGE_INC+"/cmsat"],
++                  include_dirs = [SAGE_INC, SAGE_INC+"cmsat"],
+                   language = "c++",
+                   libraries = ['cryptominisat', 'z'])
+         ])
diff --git a/sagemath-ecl-unicode.patch b/sagemath-ecl-unicode.patch
new file mode 100644
index 0000000..060b8d6
--- /dev/null
+++ b/sagemath-ecl-unicode.patch
@@ -0,0 +1,100 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/libs/ecl.pxd.orig sage-5.8/spkg/build/sage-5.8/sage/libs/ecl.pxd
+--- sage-5.8/spkg/build/sage-5.8/sage/libs/ecl.pxd.orig	2013-03-19 16:11:17.358705144 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/libs/ecl.pxd	2013-03-19 16:11:27.719705541 -0300
+@@ -133,6 +133,7 @@ cdef extern from "ecl/ecl.h":
+     cl_object ecl_read_from_cstring_safe(char *s, cl_object err)
+     cl_object cl_write_to_string(cl_narg narg, cl_object o) 
+     cl_object ecl_cstring_to_base_string_or_nil(char *s)
++    cl_object si_coerce_to_base_string(cl_object x)
+     
+     # S-expr evaluation and function calls
+     
+diff -up sage-5.8/spkg/build/sage-5.8/sage/libs/ecl.pyx.orig sage-5.8/spkg/build/sage-5.8/sage/libs/ecl.pyx
+--- sage-5.8/spkg/build/sage-5.8/sage/libs/ecl.pyx.orig	2013-03-19 16:11:07.489704766 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/libs/ecl.pyx	2013-03-19 16:11:27.719705541 -0300
+@@ -238,17 +238,19 @@ cdef cl_object ecl_safe_eval(cl_object f
+         ...
+         RuntimeError: ECL says: Console interrupt.
+     """
++    cdef cl_object s
+     ecl_sig_on()
+     cl_funcall(2,safe_eval_clobj,form)
+     ecl_sig_off()
+ 
+     if ecl_nvalues > 1:
+-        raise RuntimeError, "ECL says: "+ecl_base_string_pointer_safe(ecl_values(1))
++        s = si_coerce_to_base_string(ecl_values(1))
++        raise RuntimeError, "ECL says: "+ecl_base_string_pointer_safe(s)
+     else:
+         return ecl_values(0)
+ 
+ cdef cl_object ecl_safe_funcall(cl_object func, cl_object arg) except NULL:
+-    cdef cl_object l
++    cdef cl_object l, s
+     l = cl_cons(func,cl_cons(arg,Cnil));
+ 
+     ecl_sig_on()
+@@ -256,17 +258,20 @@ cdef cl_object ecl_safe_funcall(cl_objec
+     ecl_sig_off()
+ 
+     if ecl_nvalues > 1:
+-        raise RuntimeError, "ECL says: "+ecl_base_string_pointer_safe(ecl_values(1))
++        s = si_coerce_to_base_string(ecl_values(1))
++        raise RuntimeError, "ECL says: "+ecl_base_string_pointer_safe(s)
+     else:
+         return ecl_values(0)
+ 
+ cdef cl_object ecl_safe_apply(cl_object func, cl_object args) except NULL:
++    cdef cl_object s
+     ecl_sig_on()
+     cl_funcall(3,safe_apply_clobj,func,args)
+     ecl_sig_off()
+ 
+     if ecl_nvalues > 1:
+-        raise RuntimeError, "ECL says: "+ecl_base_string_pointer_safe(ecl_values(1))
++        s = si_coerce_to_base_string(ecl_values(1))
++        raise RuntimeError, "ECL says: "+ecl_base_string_pointer_safe(s)
+     else:
+         return ecl_values(0)
+ 
+@@ -316,10 +321,11 @@ def print_objects():
+         HELLO
+     """
+     
+-    cdef cl_object c
++    cdef cl_object c, s
+     c = list_of_objects
+     while True:
+-        print ecl_base_string_pointer_safe(cl_write_to_string(1,cl_car(c)))
++        s = si_coerce_to_base_string(cl_write_to_string(1,cl_car(c)))
++        print ecl_base_string_pointer_safe(s)
+         c=cl_cadr(c)
+         if c == Cnil:
+             break
+@@ -394,6 +400,7 @@ cdef cl_object python_to_ecl(pyobj) exce
+         raise TypeError,"Unimplemented type for python_to_ecl"
+ 
+ cdef ecl_to_python(cl_object o):
++    cdef cl_object s
+     cdef Integer N
+     # conversions from an ecl object to a python object.
+ 
+@@ -428,7 +435,8 @@ cdef ecl_to_python(cl_object o):
+                 return tuple(L)
+         return L
+     else:
+-        return ecl_base_string_pointer_safe(cl_write_to_string(1,o))
++        s = si_coerce_to_base_string(cl_write_to_string(1,o))
++        return ecl_base_string_pointer_safe(s)
+ 
+ #Maxima's BFLOAT multiprecision float type can be read with:
+ #def bfloat_to_python(e):
+@@ -644,7 +652,7 @@ cdef class EclObject:
+ 
+         """
+         cdef cl_object s
+-        s = cl_write_to_string(1,self.obj)
++        s = si_coerce_to_base_string(cl_write_to_string(1,self.obj))
+         return ecl_base_string_pointer_safe(s)
+ 
+     def __hash__(self):
diff --git a/sagemath-extensions.patch b/sagemath-extensions.patch
new file mode 100644
index 0000000..299ce7d
--- /dev/null
+++ b/sagemath-extensions.patch
@@ -0,0 +1,13 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+--- sage-5.8/spkg/build/sage-5.8/module_list.py.orig	2013-03-19 15:53:00.047663124 -0300
++++ sage-5.8/spkg/build/sage-5.8/module_list.py	2013-03-19 15:53:10.095663509 -0300
+@@ -1983,7 +1983,8 @@ ext_modules = [
+ # These extensions are to be compiled only if the
+ # corresponding packages have been installed
+ 
+-from sage.misc.package import is_package_installed
++def is_package_installed(name):
++    return False
+ 
+ if is_package_installed('fes'):
+     ext_modules.extend([
diff --git a/sagemath-fes.patch b/sagemath-fes.patch
new file mode 100644
index 0000000..d554256
--- /dev/null
+++ b/sagemath-fes.patch
@@ -0,0 +1,12 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+--- sage-5.8/spkg/build/sage-5.8/module_list.py.orig	2013-03-19 18:13:55.457986912 -0300
++++ sage-5.8/spkg/build/sage-5.8/module_list.py	2013-03-19 18:14:03.785987230 -0300
+@@ -1988,7 +1988,7 @@ ext_modules = [
+ def is_package_installed(name):
+     return False
+ 
+-if is_package_installed('fes'):
++if 1:
+     ext_modules.extend([
+        Extension("sage.libs.fes",
+                  ["sage/libs/fes.pyx"],
diff --git a/sagemath-fplll.patch b/sagemath-fplll.patch
new file mode 100644
index 0000000..c543dfe
--- /dev/null
+++ b/sagemath-fplll.patch
@@ -0,0 +1,194 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+--- sage-5.8/spkg/build/sage-5.8/module_list.py.orig	2013-03-19 18:10:02.994978010 -0300
++++ sage-5.8/spkg/build/sage-5.8/module_list.py	2013-03-19 18:10:19.754978651 -0300
+@@ -660,6 +660,7 @@ ext_modules = [
+               libraries = ['gmp', 'mpfr', 'stdc++', 'fplll'],
+               language="c++",
+               include_dirs = [SAGE_INC + 'fplll'],
++              extra_compile_args=["-DFPLLL_V3_COMPAT"],
+               depends = [SAGE_INC + "fplll/fplll.h"]),
+ 
+     Extension('sage.libs.linbox.linbox',
+diff -up sage-5.8/spkg/build/sage-5.8/sage/libs/fplll/fplll.pxi.orig sage-5.8/spkg/build/sage-5.8/sage/libs/fplll/fplll.pxi
+--- sage-5.8/spkg/build/sage-5.8/sage/libs/fplll/fplll.pxi.orig	2013-03-19 18:10:17.008978546 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/libs/fplll/fplll.pxi	2013-03-19 18:10:19.755978652 -0300
+@@ -10,22 +10,22 @@ cdef extern from "fplll/fplll.h":
+ #
+ 
+ cdef extern from "fplll/nr.h":
+-    ctypedef struct Z_NR "Z_NR<mpz_t>":
++    ctypedef struct Z_NR "fplll::Z_NR<mpz_t>":
+         mpz_t (*GetData)()
+         void (*set_mpz_t "set")(mpz_t d)
+ 
+-    Z_NR *Z_NR_new "new Z_NR<mpz_t>"()
++    Z_NR *Z_NR_new "new fplll::Z_NR<mpz_t>"()
+     void Z_NR_delete "delete "(Z_NR *mem)
+ 
+-    Z_NR *Z_NR_construct "Construct< Z_NR<mpz_t> >"(void *mem)
+-    void Z_NR_destruct "Destruct< Z_NR<mpz_t> >"(Z_NR *mem)
++    Z_NR *Z_NR_construct "Construct< fplll::Z_NR<mpz_t> >"(void *mem)
++    void Z_NR_destruct "Destruct< fplll::Z_NR<mpz_t> >"(Z_NR *mem)
+ 
+ #
+ # matrices over the integers
+ #
+ 
+ cdef extern from "fplll/matrix.h":
+-    ctypedef struct ZZ_mat "ZZ_mat<mpz_t>":
++    ctypedef struct ZZ_mat "fplll::ZZ_mat<mpz_t>":
+         int (*GetNumCols)()
+         int (*GetNumRows)()
+ 
+@@ -41,83 +41,83 @@ cdef extern from "fplll/matrix.h":
+         void (*gen_ntrulike2)(int bits,int q)
+         void (*gen_ajtai)(double alpha)
+ 
+-    ZZ_mat *ZZ_mat_new "new ZZ_mat<mpz_t>"(int r, int c)
++    ZZ_mat *ZZ_mat_new "new fplll::ZZ_mat<mpz_t>"(int r, int c)
+     void ZZ_mat_delete "delete "(ZZ_mat *mem)
+ 
+ #
+ # fastest LLL
+ #
+ 
+-cdef  extern from "fplll/fast.h":
+-    ctypedef struct fast_double "fast<mpz_t,double>":
++cdef  extern from "fplll/fplllv31.h":
++    ctypedef struct fast_double "fplll::fast<mpz_t,double>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    fast_double *fast_double_new "new fast<mpz_t,double>"(ZZ_mat *B,int precision, double eta, double delta)
++    fast_double *fast_double_new "new fplll::fast<mpz_t,double>"(ZZ_mat *B,int precision, double eta, double delta)
+     void fast_double_delete "delete "(fast_double *mem)
+ 
+ #
+ # fastest LLL with early reduction
+ #
+ 
+-cdef  extern from "fplll/fast_earlyred.h":
+-    ctypedef struct fast_early_red_double "fast_early_red<mpz_t,double>":
++cdef  extern from "fplll/fplllv31.h":
++    ctypedef struct fast_early_red_double "fplll::fast_early_red<mpz_t,double>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    fast_early_red_double *fast_early_red_double_new "new fast_early_red<mpz_t,double>"(ZZ_mat *B,int precision, double eta, double delta)
++    fast_early_red_double *fast_early_red_double_new "new fplll::fast_early_red<mpz_t,double>"(ZZ_mat *B,int precision, double eta, double delta)
+     void fast_early_red_double_delete "delete "(fast_early_red_double *mem)
+ 
+ #
+ # heuristic
+ #
+ 
+-cdef  extern from "fplll/heuristic.h":
+-    ctypedef struct heuristic_mpfr "heuristic<mpz_t,mpfr_t>":
++cdef  extern from "fplll/fplllv31.h":
++    ctypedef struct heuristic_mpfr "fplll::heuristic<mpz_t,mpfr_t>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    heuristic_mpfr *heuristic_mpfr_new "new heuristic<mpz_t,mpfr_t>"(ZZ_mat *B,int precision, double eta, double delta)
++    heuristic_mpfr *heuristic_mpfr_new "new fplll::heuristic<mpz_t,mpfr_t>"(ZZ_mat *B,int precision, double eta, double delta)
+     void heuristic_mpfr_delete "delete "(heuristic_mpfr *mem)
+ 
+-    ctypedef struct heuristic_dpe "heuristic<mpz_t,dpe_t>":
++    ctypedef struct heuristic_dpe "fplll::heuristic<mpz_t,dpe_t>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    heuristic_dpe *heuristic_dpe_new "new heuristic<mpz_t,dpe_t>"(ZZ_mat *B,int precision, double eta, double delta)
++    heuristic_dpe *heuristic_dpe_new "new fplll::heuristic<mpz_t,dpe_t>"(ZZ_mat *B,int precision, double eta, double delta)
+     void heuristic_dpe_delete "delete "(heuristic_dpe *mem)
+ 
+-    ctypedef struct heuristic_double "heuristic<mpz_t,double>":
++    ctypedef struct heuristic_double "fplll::heuristic<mpz_t,double>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    heuristic_double *heuristic_double_new "new heuristic<mpz_t,double>"(ZZ_mat *B,int precision, double eta, double delta)
++    heuristic_double *heuristic_double_new "new fplll::heuristic<mpz_t,double>"(ZZ_mat *B,int precision, double eta, double delta)
+     void heuristic_double_delete "delete "(heuristic_double *mem)
+ 
+ #
+ # heuristic with early reduction
+ #
+ 
+-cdef  extern from "fplll/heuristic_early_red.h":
+-    ctypedef struct heuristic_early_red_mpfr "heuristic_early_red<mpz_t,mpfr_t>":
++cdef  extern from "fplll/fplllv31.h":
++    ctypedef struct heuristic_early_red_mpfr "fplll::heuristic_early_red<mpz_t,mpfr_t>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    heuristic_early_red_mpfr *heuristic_early_red_mpfr_new "new heuristic_early_red<mpz_t,mpfr_t>"(ZZ_mat *B,int precision, double eta, double delta)
++    heuristic_early_red_mpfr *heuristic_early_red_mpfr_new "new fplll::heuristic_early_red<mpz_t,mpfr_t>"(ZZ_mat *B,int precision, double eta, double delta)
+     void heuristic_early_red_mpfr_delete "delete "(heuristic_early_red_mpfr *mem)
+ 
+-    ctypedef struct heuristic_early_red_dpe "heuristic_early_red<mpz_t,dpe_t>":
++    ctypedef struct heuristic_early_red_dpe "fplll::heuristic_early_red<mpz_t,dpe_t>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    heuristic_early_red_dpe *heuristic_early_red_dpe_new "new heuristic_early_red<mpz_t,dpe_t>"(ZZ_mat *B,int precision, double eta, double delta)
++    heuristic_early_red_dpe *heuristic_early_red_dpe_new "new fplll::heuristic_early_red<mpz_t,dpe_t>"(ZZ_mat *B,int precision, double eta, double delta)
+     void heuristic_early_red_dpe_delete "delete "(heuristic_early_red_dpe *mem)
+ 
+-    ctypedef struct heuristic_early_red_double "heuristic_early_red<mpz_t,double>":
++    ctypedef struct heuristic_early_red_double "fplll::heuristic_early_red<mpz_t,double>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    heuristic_early_red_double *heuristic_early_red_double_new "new heuristic_early_red<mpz_t,double>"(ZZ_mat *B,int precision, double eta, double delta)
++    heuristic_early_red_double *heuristic_early_red_double_new "new fplll::heuristic_early_red<mpz_t,double>"(ZZ_mat *B,int precision, double eta, double delta)
+     void heuristic_early_red_double_delete "delete "(heuristic_early_red_double *mem)
+ 
+ 
+@@ -126,36 +126,36 @@ cdef  extern from "fplll/heuristic_early
+ # provable LLL
+ #
+ 
+-cdef  extern from "fplll/proved.h":
+-    ctypedef struct proved_mpfr "proved<mpz_t,mpfr_t>":
++cdef  extern from "fplll/fplllv31.h":
++    ctypedef struct proved_mpfr "fplll::proved<mpz_t,mpfr_t>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    proved_mpfr *proved_mpfr_new "new proved<mpz_t,mpfr_t>"(ZZ_mat *B,int precision, double eta, double delta)
++    proved_mpfr *proved_mpfr_new "new fplll::proved<mpz_t,mpfr_t>"(ZZ_mat *B,int precision, double eta, double delta)
+     void proved_mpfr_delete "delete "(proved_mpfr *mem)
+ 
+-    ctypedef struct proved_dpe "proved<mpz_t,dpe_t>":
++    ctypedef struct proved_dpe "fplll::proved<mpz_t,dpe_t>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    proved_dpe *proved_dpe_new "new proved<mpz_t,dpe_t>"(ZZ_mat *B,int precision, double eta, double delta)
++    proved_dpe *proved_dpe_new "new fplll::proved<mpz_t,dpe_t>"(ZZ_mat *B,int precision, double eta, double delta)
+     void proved_dpe_delete "delete "(proved_dpe *mem)
+ 
+-    ctypedef struct proved_double "proved<mpz_t,double>":
++    ctypedef struct proved_double "fplll::proved<mpz_t,double>":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    proved_double *proved_double_new "new proved<mpz_t,double>"(ZZ_mat *B,int precision, double eta, double delta)
++    proved_double *proved_double_new "new fplll::proved<mpz_t,double>"(ZZ_mat *B,int precision, double eta, double delta)
+     void proved_double_delete "delete "(proved_double *mem)
+ 
+ #
+ # wrapper code which chooses a LLL sequence automatically
+ #
+ 
+-cdef  extern from "fplll/wrapper.h":
+-    ctypedef struct wrapper:
++cdef  extern from "fplll/fplllv31.h":
++    ctypedef struct wrapper "fplll::wrapper":
+       int (*LLL)()
+       ZZ_mat* (*GetBase)()
+ 
+-    wrapper *wrapper_new "new wrapper"(ZZ_mat *B,int precision, double eta, double delta)
++    wrapper *wrapper_new "new fplll::wrapper"(ZZ_mat *B,int precision, double eta, double delta)
+     void wrapper_delete "delete "(wrapper *mem)
diff --git a/sagemath-gap-hap.patch b/sagemath-gap-hap.patch
new file mode 100644
index 0000000..0f13901
--- /dev/null
+++ b/sagemath-gap-hap.patch
@@ -0,0 +1,23 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/groups/perm_gps/permgroup.py.orig sage-5.8/spkg/build/sage-5.8/sage/groups/perm_gps/permgroup.py
+--- sage-5.8/spkg/build/sage-5.8/sage/groups/perm_gps/permgroup.py.orig	2013-03-19 16:22:36.592731155 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/groups/perm_gps/permgroup.py	2013-03-19 16:22:58.320731987 -0300
+@@ -180,8 +180,7 @@ def hap_decorator(f):
+     """
+     @wraps(f)
+     def wrapped(self, n, p=0):
+-        if not is_package_installed('gap_packages'):
+-            raise RuntimeError, "You must install the optional gap_packages package."
++        raise RuntimeError, "gap-hap package not available."
+         load_hap()
+         from sage.rings.arith import is_prime
+         if not (p == 0 or is_prime(p)):
+@@ -3628,8 +3627,7 @@ class PermutationGroup_generic(group.Gro
+ 
+         - David Joyner and Graham Ellis
+         """
+-        if not is_package_installed('gap_packages'):
+-            raise RuntimeError, "You must install the optional gap_packages package."
++        raise RuntimeError, "gap-hap package not available."
+         load_hap()
+         from sage.rings.arith import is_prime
+         if not (p == 0 or is_prime(p)):
diff --git a/sagemath-gmp.patch b/sagemath-gmp.patch
new file mode 100644
index 0000000..7b02eb2
--- /dev/null
+++ b/sagemath-gmp.patch
@@ -0,0 +1,11 @@
+--- sage-5.8/spkg/build/sage-5.8/c_lib/src/memory.c.orig	2012-07-10 11:46:54.516595967 -0400
++++ sage-5.8/spkg/build/sage-5.8/c_lib/src/memory.c	2012-07-10 11:47:12.688596755 -0400
+@@ -17,7 +17,7 @@ AUTHORS:
+  *                  http://www.gnu.org/licenses/
+  ****************************************************************************/
+ 
+-#include <mpir.h>
++#include <gmp.h>
+ #include "memory.h"
+ 
+ /* mpir memory functions */
diff --git a/sagemath-jmol.patch b/sagemath-jmol.patch
new file mode 100644
index 0000000..d5eb232
--- /dev/null
+++ b/sagemath-jmol.patch
@@ -0,0 +1,30 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/interfaces/jmoldata.py.orig sage-5.8/spkg/build/sage-5.8/sage/interfaces/jmoldata.py
+--- sage-5.8/spkg/build/sage-5.8/sage/interfaces/jmoldata.py.orig	2012-11-10 12:03:07.742817945 -0200
++++ sage-5.8/spkg/build/sage-5.8/sage/interfaces/jmoldata.py	2012-11-10 12:03:34.499818970 -0200
+@@ -86,7 +86,7 @@ class JmolData(SageObject):
+             sage_makedirs(jmolscratch)
+         scratchout = os.path.join(jmolscratch,"jmolout.txt")
+         jout=open(scratchout,'w')
+-        testjavapath = os.path.join(SAGE_LOCAL, "share", "jmol", "testjava.sh")
++        testjavapath = os.path.join(SAGE_LOCAL, "bin", "testjava.sh")
+         result = subprocess.call([testjavapath],stdout=jout)
+         jout.close()
+         if (result == 0):
+@@ -167,8 +167,6 @@ class JmolData(SageObject):
+ 
+          """
+         if (self.is_jvm_available()):
+-            # Set up paths, file names and scripts
+-            jmolpath = os.path.join(SAGE_LOCAL, "share", "jmol", "JmolData.jar")
+             launchscript = ""
+             if (datafile_cmd!='script'):
+                 launchscript = "load "
+@@ -185,7 +183,7 @@ class JmolData(SageObject):
+             scratchout = os.path.join(jmolscratch,"jmolout.txt")
+             jout=open(scratchout,'w')
+             #now call the java application and write the file.
+-            result = subprocess.call(["java","-Xmx512m","-Djava.awt.headless=true","-jar",jmolpath,"-iox","-g",sizeStr,"-J",launchscript,"-j",imagescript],stdout=jout)
++            result = subprocess.call(["jmol","-n","-g",sizeStr,"-J",launchscript,"-j",imagescript],stdout=jout)
+             jout.close()
+         else:
+             errStr = "Java Virtual Machine not available.\n"
diff --git a/sagemath-libgap.patch b/sagemath-libgap.patch
new file mode 100644
index 0000000..3558c2c
--- /dev/null
+++ b/sagemath-libgap.patch
@@ -0,0 +1,2 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+diff -up sage-5.8/spkg/build/sage-5.8/sage/libs/gap/util.pyx.orig sage-5.8/spkg/build/sage-5.8/sage/libs/gap/util.pyx
diff --git a/sagemath-libmpc.patch b/sagemath-libmpc.patch
new file mode 100644
index 0000000..f35382b
--- /dev/null
+++ b/sagemath-libmpc.patch
@@ -0,0 +1,65 @@
+diff -up sage-5.8/spkg/build/sage-5.8/c_lib/SConstruct.orig sage-5.8/spkg/build/sage-5.8/c_lib/SConstruct
+--- sage-5.8/spkg/build/sage-5.8/c_lib/SConstruct.orig	2013-02-23 12:42:08.694809731 -0300
++++ sage-5.8/spkg/build/sage-5.8/c_lib/SConstruct	2013-02-23 12:43:00.412811711 -0300
+@@ -145,7 +145,7 @@ soname = libname + "." + major
+ shlink_flags += [ '-Wl,-Bsymbolic', '-Wl,-soname=%s' % soname ]
+ 
+ lib = env.SharedLibrary( "csage", [ "src/" + x for x in srcFiles ],
+-                         LIBS=['ntl', 'pari', 'gmp', 'python$PYV'], 
++                         LIBS=['ntl', 'pari', 'gmp', 'mpfr', 'python$PYV'], 
+                          LIBPATH=['@@libdir@@','@@libdir@@/python$PYV/config/'],
+                          SHLIBSUFFIX=shlib_suffix,
+                          SHLINKFLAGS=shlink_flags,
+diff -up sage-5.8/spkg/build/sage-5.8/c_lib/src/stdsage.c.orig sage-5.8/spkg/build/sage-5.8/c_lib/src/stdsage.c
+--- sage-5.8/spkg/build/sage-5.8/c_lib/src/stdsage.c.orig	2013-02-23 12:42:18.286810098 -0300
++++ sage-5.8/spkg/build/sage-5.8/c_lib/src/stdsage.c	2013-02-23 12:43:15.062812272 -0300
+@@ -58,3 +58,49 @@ void init_csage_module() {
+     init_csage();
+ #endif
+ }
++
++#include <mpc.h>
++
++int
++mpc_div_2ui (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd)
++{
++  int inex_re, inex_im;
++
++  inex_re = mpfr_div_2ui (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
++  inex_im = mpfr_div_2ui (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
++
++  return MPC_INEX(inex_re, inex_im);
++}
++
++int
++mpc_div_2si (mpc_ptr a, mpc_srcptr b, long int c, mpc_rnd_t rnd)
++{
++  int inex_re, inex_im;
++
++  inex_re = mpfr_div_2si (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
++  inex_im = mpfr_div_2si (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
++
++  return MPC_INEX(inex_re, inex_im);
++}
++
++int
++mpc_mul_2ui (mpc_ptr a, mpc_srcptr b, unsigned long int c, mpc_rnd_t rnd)
++{
++  int inex_re, inex_im;
++
++  inex_re = mpfr_mul_2ui (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
++  inex_im = mpfr_mul_2ui (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
++
++  return MPC_INEX(inex_re, inex_im);
++}
++
++int
++mpc_mul_2si (mpc_ptr a, mpc_srcptr b, long int c, mpc_rnd_t rnd)
++{
++  int inex_re, inex_im;
++
++  inex_re = mpfr_mul_2si (mpc_realref(a), mpc_realref(b), c, MPC_RND_RE(rnd));
++  inex_im = mpfr_mul_2si (mpc_imagref(a), mpc_imagref(b), c, MPC_RND_IM(rnd));
++
++  return MPC_INEX(inex_re, inex_im);
++}
diff --git a/sagemath-lrcalc.patch b/sagemath-lrcalc.patch
new file mode 100644
index 0000000..41d04cd
--- /dev/null
+++ b/sagemath-lrcalc.patch
@@ -0,0 +1,12 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+--- sage-5.8/spkg/build/sage-5.8/module_list.py.orig	2013-03-19 18:11:46.450981971 -0300
++++ sage-5.8/spkg/build/sage-5.8/module_list.py	2013-03-19 18:11:55.761982328 -0300
+@@ -2064,7 +2064,7 @@ if UNAME[0] == "Darwin" and not UNAME[2]
+         )
+ 
+ 
+-if is_package_installed('lrcalc'):
++if 1:
+     ext_modules.append(
+         Extension('sage.libs.lrcalc.lrcalc',
+                   sources = ["sage/libs/lrcalc/lrcalc.pyx"],
diff --git a/sagemath-lrslib.patch b/sagemath-lrslib.patch
new file mode 100644
index 0000000..8840ff0
--- /dev/null
+++ b/sagemath-lrslib.patch
@@ -0,0 +1,15 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/geometry/polyhedron/base.py.orig sage-5.8/spkg/build/sage-5.8/sage/geometry/polyhedron/base.py
+--- sage-5.8/spkg/build/sage-5.8/sage/geometry/polyhedron/base.py.orig	2013-03-19 16:20:52.760727178 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/geometry/polyhedron/base.py	2013-03-19 16:21:00.096727459 -0300
+@@ -3129,11 +3129,6 @@ class Polyhedron_base(Element):
+ 
+              David Avis's lrs program.
+         """
+-        if is_package_installed('lrs') != True:
+-            print 'You must install the optional lrs package ' \
+-                  'for this function to work'
+-            raise NotImplementedError
+-
+         in_str = self.cdd_Vrepresentation()
+         in_str += 'volume'
+         in_filename = tmp_filename()
diff --git a/sagemath-maxima.patch b/sagemath-maxima.patch
new file mode 100644
index 0000000..4aac0e9
--- /dev/null
+++ b/sagemath-maxima.patch
@@ -0,0 +1,35 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/interfaces/maxima.py.orig sage-5.8/spkg/build/sage-5.8/sage/interfaces/maxima.py
+--- sage-5.8/spkg/build/sage-5.8/sage/interfaces/maxima.py.orig	2012-08-04 13:21:54.100575138 -0400
++++ sage-5.8/spkg/build/sage-5.8/sage/interfaces/maxima.py	2012-08-04 13:22:15.580575956 -0400
+@@ -544,7 +544,7 @@ class Maxima(MaximaAbstract, Expect):
+         Expect.__init__(self,
+                         name = 'maxima',
+                         prompt = '\(\%i[0-9]+\)',
+-                        command = 'maxima-noreadline --userdir="%s" -p "%s"'%(SAGE_MAXIMA_DIR,STARTUP), 
++                        command = 'maxima --disable-readline --userdir="%s" -p "%s"'%(SAGE_MAXIMA_DIR,STARTUP), 
+                         maxread = 10000,
+                         script_subdirectory = script_subdirectory,
+                         restart_on_ctrlc = False,
+@@ -588,7 +588,8 @@ class Maxima(MaximaAbstract, Expect):
+ 
+         # Remove limit on the max heapsize (since otherwise it defaults
+         # to 256MB with ECL).
+-        self._sendline(":lisp (ext:set-limit 'ext:heap-size 0)")
++        self._sendline(":lisp #+ecl (ext:set-limit 'ext:heap-size 0) #-ecl 0")
++        self._sendline(':lisp #+gcl (progn (si:readline-off) (setf *error-output* (open "/dev/stderr" :direction :output)  *standard-input* (open "/dev/stdin" :direction :input)  *standard-output* (open "/dev/stdout" :direction :output))) #-gcl t')
+         self._eval_line('0;')
+ 
+     def __reduce__(self):
+diff -up sage-5.8/spkg/build/sage_scripts-5.7/sage-maxima.lisp.orig sage-5.8/spkg/build/sage_scripts-5.7/sage-maxima.lisp
+--- sage-5.8/spkg/build/sage_scripts-5.8/sage-maxima.lisp.orig	2012-08-04 13:22:07.842575668 -0400
++++ sage-5.8/spkg/build/sage_scripts-5.8/sage-maxima.lisp	2012-08-04 13:22:15.580575956 -0400
+@@ -3,4 +3,8 @@
+ ;(setf *general-display-prefix* "<sage-display>")
+ 
+ (setf *prompt-prefix* "<sage-display>")
+-
++#+clisp
++(setf
++  *error-output* (open "/dev/stderr" :direction :output)
++  *standard-input* (open "/dev/stdin" :direction :input)
++  *standard-output* (open "/dev/stdout" :direction :output))
diff --git a/sagemath-maxima.system.patch b/sagemath-maxima.system.patch
new file mode 100644
index 0000000..acbf36d
--- /dev/null
+++ b/sagemath-maxima.system.patch
@@ -0,0 +1,12 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/interfaces/maxima_lib.py.orig sage-5.8/spkg/build/sage-5.8/sage/interfaces/maxima_lib.py
+--- sage-5.8/spkg/build/sage-5.8/sage/interfaces/maxima_lib.py.orig	2012-12-29 15:42:54.811218546 -0200
++++ sage-5.8/spkg/build/sage-5.8/sage/interfaces/maxima_lib.py	2012-12-29 15:43:06.739219003 -0200
+@@ -77,7 +77,7 @@ from maxima_abstract import (MaximaAbstr
+ ## We begin here by initializing Maxima in library mode
+ ## i.e. loading it into ECL
+ ecl_eval("(setf *load-verbose* NIL)")
+-ecl_eval("(require 'maxima)")
++ecl_eval("(require 'maxima.system)")
+ ecl_eval("(in-package :maxima)")
+ ecl_eval("(setq $nolabels t))")
+ ecl_eval("(defvar *MAXIMA-LANG-SUBDIR* NIL)")
diff --git a/sagemath-nauty.patch b/sagemath-nauty.patch
new file mode 100644
index 0000000..63d6c29
--- /dev/null
+++ b/sagemath-nauty.patch
@@ -0,0 +1,13 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/graphs/graph_generators.py.orig sage-5.8/spkg/build/sage-5.8/sage/graphs/graph_generators.py
+--- sage-5.8/spkg/build/sage-5.8/sage/graphs/graph_generators.py.orig	2013-02-22 17:34:47.243877299 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/graphs/graph_generators.py	2013-02-22 17:34:56.066877637 -0300
+@@ -769,8 +769,7 @@ class GraphGenerators():
+         """
+         import subprocess
+         from sage.misc.package import is_package_installed
+-        if not is_package_installed("nauty"):
+-            raise TypeError, "the optional nauty package is not installed"
++        raise TypeError, "the optional nauty package is not installed"
+         sp = subprocess.Popen("nauty-geng {0}".format(options), shell=True,
+                               stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                               stderr=subprocess.PIPE, close_fds=True)
diff --git a/sagemath-nolibgap.patch b/sagemath-nolibgap.patch
new file mode 100644
index 0000000..b8c2864
--- /dev/null
+++ b/sagemath-nolibgap.patch
@@ -0,0 +1,55 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+--- sage-5.8/spkg/build/sage-5.8/module_list.py.orig	2013-03-19 16:34:20.048758092 -0300
++++ sage-5.8/spkg/build/sage-5.8/module_list.py	2013-03-19 16:34:33.078758591 -0300
+@@ -498,8 +498,8 @@ ext_modules = [
+     Extension('sage.groups.old',
+               sources = ['sage/groups/old.pyx']),
+ 
+-    Extension('sage.groups.libgap_wrapper',
+-              sources = ['sage/groups/libgap_wrapper.pyx']),
++#    Extension('sage.groups.libgap_wrapper',
++#              sources = ['sage/groups/libgap_wrapper.pyx']),
+ 
+     Extension('sage.groups.perm_gps.permgroup_element',
+               sources = ['sage/groups/perm_gps/permgroup_element.pyx']),
+@@ -793,25 +793,25 @@ ext_modules = [
+         ##
+         ################################
+ 
+-    Extension('sage.libs.gap.util',
+-              sources = ["sage/libs/gap/util.pyx"],
+-              libraries = ['csage', 'gmp', 'gap', 'm'],
+-              include_dirs = [SAGE_LOCAL + '/include/']),
+-
+-    Extension('sage.libs.gap.element',
+-              sources = ["sage/libs/gap/element.pyx"],
+-              libraries = ['csage', 'gmp', 'gap', 'm'],
+-              include_dirs = [SAGE_LOCAL + '/include/']),
+-
++#    Extension('sage.libs.gap.util',
++#              sources = ["sage/libs/gap/util.pyx"],
++#              libraries = ['csage', 'gmp', 'gap', 'm'],
++#              include_dirs = [SAGE_INC]),
++#
++#    Extension('sage.libs.gap.element',
++#              sources = ["sage/libs/gap/element.pyx"],
++#              libraries = ['csage', 'gmp', 'gap', 'm'],
++#              include_dirs = [SAGE_INC]),
++#
+     # Extension('sage.libs.gap.type',
+     #           sources = ["sage/libs/gap/type.pyx"],
+     #           libraries = ['csage', 'gmp', 'gap', 'm'],
+     #           include_dirs = [SAGE_LOCAL + '/include/']),
+-    
+-    Extension('sage.libs.gap.libgap',
+-              sources = ["sage/libs/gap/libgap.pyx"],
+-              libraries = ['csage', 'gmp', 'gap', 'm'],
+-              include_dirs = [SAGE_LOCAL + '/include/']),
++#    
++#    Extension('sage.libs.gap.libgap',
++#              sources = ["sage/libs/gap/libgap.pyx"],
++#              libraries = ['csage', 'gmp', 'gap', 'm'],
++#              include_dirs = [SAGE_INC]),
+ 
+         ###################################
+         ##
diff --git a/sagemath-nopari2.6.patch b/sagemath-nopari2.6.patch
new file mode 100644
index 0000000..fd30e93
--- /dev/null
+++ b/sagemath-nopari2.6.patch
@@ -0,0 +1,25 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/libs/pari/decl.pxi.orig sage-5.8/spkg/build/sage-5.8/sage/libs/pari/decl.pxi
+--- sage-5.8/spkg/build/sage-5.8/sage/libs/pari/decl.pxi.orig	2013-03-19 17:20:25.960864009 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/libs/pari/decl.pxi	2013-03-19 17:20:33.246864288 -0300
+@@ -595,7 +595,6 @@ cdef extern from 'pari/pari.h':
+     GEN     polredabs0(GEN x, long flag)
+     GEN     polredabs2(GEN x)
+     GEN     polredabsall(GEN x, long flun)
+-    GEN     polredbest(GEN x, long flag)
+     GEN     qflll0(GEN x, long flag)
+     GEN     qflllgram0(GEN x, long flag)
+     GEN     smallpolred(GEN x)
+diff -up sage-5.8/spkg/build/sage-5.8/sage/libs/pari/gen.pyx.orig sage-5.8/spkg/build/sage-5.8/sage/libs/pari/gen.pyx
+--- sage-5.8/spkg/build/sage-5.8/sage/libs/pari/gen.pyx.orig	2013-03-19 17:20:55.992865159 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/libs/pari/gen.pyx	2013-03-19 17:21:02.118865393 -0300
+@@ -8011,10 +8011,6 @@ cdef class gen(sage.structure.element.Ri
+         sig_on()
+         return self.new_gen(polredabs0(self.g, flag))
+ 
+-    def polredbest(self, flag=0):
+-        sig_on()
+-        return self.new_gen(polredbest(self.g, flag))
+-
+     def polresultant(self, y, var=-1, flag=0):
+         t0GEN(y)
+         sig_on()
diff --git a/sagemath-pari.patch b/sagemath-pari.patch
new file mode 100644
index 0000000..a2c91ad
--- /dev/null
+++ b/sagemath-pari.patch
@@ -0,0 +1,41 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/interfaces/gp.py.orig sage-5.8/spkg/build/sage-5.8/sage/interfaces/gp.py
+--- sage-5.8/spkg/build/sage-5.8/sage/interfaces/gp.py.orig	2013-03-19 16:16:17.815716650 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/interfaces/gp.py	2013-03-19 16:16:27.031717003 -0300
+@@ -980,8 +980,8 @@ def is_GpElement(x):
+ from sage.misc.all import DOT_SAGE, SAGE_ROOT
+ import os
+ 
+-# Set GPRC environment variable to $SAGE_ROOT/local/etc/gprc.expect
+-os.environ["GPRC"] = '%s/local/etc/gprc.expect'%SAGE_ROOT
++# Set GPRC environment variable to $SAGE_ROOT/data/extcode/pari/gprc.expect
++os.environ["GPRC"] = '%s/data/extcode/pari/gprc.expect'%SAGE_ROOT
+ 
+ # An instance
+ gp = Gp(logfile=DOT_SAGE+'/gp-expect.log') # useful for debugging!
+diff -up sage-5.8/spkg/build/sage-5.8/sage/libs/pari/gen.pyx.orig sage-5.8/spkg/build/sage-5.8/sage/libs/pari/gen.pyx
+--- sage-5.8/spkg/build/sage-5.8/sage/libs/pari/gen.pyx.orig	2013-03-19 16:16:10.607716374 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/libs/pari/gen.pyx	2013-03-19 16:16:27.035717003 -0300
+@@ -182,6 +182,10 @@ include '../../ext/stdsage.pxi'
+ cdef extern from "mpz_pylong.h":
+     cdef int mpz_set_pylong(mpz_t dst, src) except -1
+ 
++cdef extern from "gmp.h":
++    cdef void mp_get_memory_functions(void**, void**, void**)
++    cdef void mp_set_memory_functions(void*, void*, void*)
++
+ # Make sure we don't use mpz_t_offset before initializing it by
+ # putting in a value that's likely to provoke a segmentation fault,
+ # rather than silently corrupting memory.
+@@ -9175,7 +9179,12 @@ cdef class PariInstance(sage.structure.p
+ 
+         # The size here doesn't really matter, because we will allocate
+         # our own stack anyway. We ask PARI not to set up signal handlers.
++        cdef void *_gmp_malloc
++        cdef void *_gmp_realloc
++        cdef void *_gmp_free
++        mp_get_memory_functions(&_gmp_malloc, &_gmp_realloc, &_gmp_free)
+         pari_init_opts(10000, maxprime, INIT_JMPm | INIT_DFTm)
++        mp_set_memory_functions(_gmp_malloc, _gmp_realloc, _gmp_free)
+         num_primes = maxprime
+ 
+         # NOTE: sig_on() can only come AFTER pari_init_opts()!
diff --git a/sagemath-png.patch b/sagemath-png.patch
new file mode 100644
index 0000000..9445d38
--- /dev/null
+++ b/sagemath-png.patch
@@ -0,0 +1,30 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+--- sage-5.8/spkg/build/sage-5.8/module_list.py.orig	2013-03-19 16:11:57.438706679 -0300
++++ sage-5.8/spkg/build/sage-5.8/module_list.py	2013-03-19 16:12:05.927707004 -0300
+@@ -1036,7 +1036,7 @@ ext_modules = [
+ 
+     Extension('sage.matrix.matrix_mod2_dense',
+               sources = ['sage/matrix/matrix_mod2_dense.pyx'],
+-              libraries = ['gmp','m4ri', 'gd', 'png12', 'z'],
++              libraries = ['gmp','m4ri', 'gd', 'png', 'z'],
+               extra_compile_args = ['-std=c99'] + m4ri_extra_compile_args,
+               depends = [SAGE_INC + "png.h", SAGE_INC + "m4ri/m4ri.h"]),
+ 
+@@ -1298,7 +1298,7 @@ ext_modules = [
+ 
+     Extension('sage.modules.vector_mod2_dense',
+               sources = ['sage/modules/vector_mod2_dense.pyx'],
+-              libraries = ['gmp','m4ri', 'png12', 'gd'],
++              libraries = ['gmp','m4ri', 'png', 'gd'],
+               extra_compile_args = ['-std=c99'] + m4ri_extra_compile_args,
+               depends = [SAGE_INC + "png.h", SAGE_INC + "m4ri/m4ri.h"]),
+     
+@@ -1772,7 +1772,7 @@ ext_modules = [
+ 
+     Extension('sage.rings.polynomial.pbori',
+               sources = ['sage/rings/polynomial/pbori.pyx'],
+-              libraries=['polybori', 'polybori_groebner', 'cudd', 'gd', 'png12', 'm4ri'],
++              libraries=['polybori', 'polybori_groebner', 'cudd', 'gd', 'png', 'm4ri'],
+               include_dirs = [SAGE_INC, "sage/libs/polybori"],
+               depends = [SAGE_INC + "polybori/" + hd + ".h" for hd in ["polybori", "config"] ] + \
+                         [SAGE_INC + 'm4ri/m4ri.h'],
diff --git a/sagemath-readonly.patch b/sagemath-readonly.patch
new file mode 100644
index 0000000..1bf31b6
--- /dev/null
+++ b/sagemath-readonly.patch
@@ -0,0 +1,20 @@
+diff -up sage-5.8/spkg/build/sage-5.8/sage/all.py.orig sage-5.8/spkg/build/sage-5.8/sage/all.py
+--- sage-5.8/spkg/build/sage-5.8/sage/all.py.orig	2013-02-22 17:28:29.394862830 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/all.py	2013-02-22 17:28:54.808863803 -0300
+@@ -288,13 +288,13 @@ def _write_started_file():
+ 
+     Check that the file exists when Sage is running::
+ 
+-        sage: started_file = os.path.join(SAGE_LOCAL, 'etc', 'sage-started.txt')
++        sage: started_file = os.path.join(DOT_SAGE, 'sage-started.txt')
+         sage: os.path.isfile(started_file)
+         True
+     """
+-    from sage.misc.all import SAGE_LOCAL
++    from sage.misc.all import DOT_SAGE
+ 
+-    started_file = os.path.join(SAGE_LOCAL, 'etc', 'sage-started.txt')
++    started_file = os.path.join(DOT_SAGE, 'sage-started.txt')
+     # Do nothing if the file already exists
+     if os.path.isfile(started_file):
+         return
diff --git a/sagemath-rpmbuild.patch b/sagemath-rpmbuild.patch
new file mode 100644
index 0000000..3c9928f
--- /dev/null
+++ b/sagemath-rpmbuild.patch
@@ -0,0 +1,154 @@
+diff -up sage-5.8/spkg/build/sage-5.8/module_list.py.orig sage-5.8/spkg/build/sage-5.8/module_list.py
+--- sage-5.8/spkg/build/sage-5.8/module_list.py.orig	2013-03-19 18:08:36.523974698 -0300
++++ sage-5.8/spkg/build/sage-5.8/module_list.py	2013-03-19 18:08:39.383974808 -0300
+@@ -48,10 +48,11 @@ else:
+ ### Commonly used definitions
+ #########################################################
+ 
+-numpy_include_dirs = [SAGE_LOCAL + '/lib/python/site-packages/numpy/core/include']
++from distutils.sysconfig import get_python_lib
++numpy_include_dirs = [get_python_lib(1) + '/numpy/core/include']
+ # We pick a file from numpy which is autogenerated so it has the
+ # timestamp of the numpy build.
+-numpy_depends = [SAGE_LOCAL + '/lib/python/site-packages/numpy/core/include/numpy/_numpyconfig.h']
++numpy_depends = [get_python_lib(1) + '/numpy/core/include/numpy/_numpyconfig.h']
+ 
+ flint_depends = [SAGE_INC + 'FLINT/flint.h']
+ singular_depends = [SAGE_INC + 'libsingular.h', SAGE_INC + 'givaro/givconfig.h']
+@@ -1771,7 +1772,7 @@ ext_modules = [
+ 
+     Extension('sage.rings.polynomial.pbori',
+               sources = ['sage/rings/polynomial/pbori.pyx'],
+-              libraries=['polybori', 'polybori_groebner', 'gd', 'png12', 'm4ri'],
++              libraries=['polybori', 'polybori_groebner', 'cudd', 'gd', 'png12', 'm4ri'],
+               include_dirs = [SAGE_INC, "sage/libs/polybori"],
+               depends = [SAGE_INC + "polybori/" + hd + ".h" for hd in ["polybori", "config"] ] + \
+                         [SAGE_INC + 'm4ri/m4ri.h'],
+diff -up sage-5.8/spkg/build/sage-5.8/sage/numerical/backends/glpk_backend.pxd.orig sage-5.8/spkg/build/sage-5.8/sage/numerical/backends/glpk_backend.pxd
+--- sage-5.8/spkg/build/sage-5.8/sage/numerical/backends/glpk_backend.pxd.orig	2013-03-19 18:08:36.526974699 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/numerical/backends/glpk_backend.pxd	2013-03-19 18:08:39.383974808 -0300
+@@ -16,7 +16,7 @@ cdef extern from *:
+ cdef extern from "float.h":
+     cdef double DBL_MAX
+ 
+-cdef extern from "../../../local/include/glpk.h":
++cdef extern from "glpk.h":
+      ctypedef struct c_glp_prob "glp_prob":
+          pass
+      ctypedef struct c_glp_iocp "glp_iocp":
+diff -up sage-5.8/spkg/build/sage-5.8/setup.py.orig sage-5.8/spkg/build/sage-5.8/setup.py
+--- sage-5.8/spkg/build/sage-5.8/setup.py.orig	2013-03-20 03:54:28.401811272 -0300
++++ sage-5.8/spkg/build/sage-5.8/setup.py	2013-03-20 03:54:53.892811608 -0300
+@@ -37,6 +37,11 @@ else:
+     SAGE_DEVEL = SAGE_ROOT + '/devel'
+     SAGE_INC   = SAGE_LOCAL + '/include/'
+ 
++if os.environ.has_key('DESTDIR'):
++    DESTDIR = os.environ['DESTDIR']
++else:
++    DESTDIR = ''
++
+ if not os.environ.has_key('SAGE_VERSION'):
+     SAGE_VERSION=0
+ else:
+@@ -49,21 +54,13 @@ except KeyError:
+     compile_result_dir = None
+     keep_going = False
+ 
+-SITE_PACKAGES = '%s/lib/python%s/site-packages/'%(SAGE_LOCAL,platform.python_version().rsplit('.', 1)[0])
++SITE_PACKAGES = '%s/lib/python%s/site-packages'%(SAGE_LOCAL,platform.python_version().rsplit('.', 1)[0])
+ if not os.path.exists(SITE_PACKAGES):
+     raise RuntimeError, "Unable to find site-packages directory (see setup.py file in sage python code)."
+ 
+-if not os.path.exists('build/sage'):
+-    os.makedirs('build/sage')
+-
+-sage_link = SITE_PACKAGES + '/sage'
+-if not os.path.islink(sage_link) or not os.path.exists(sage_link):
+-    os.system('rm -rf "%s"'%sage_link)
+-    os.system('cd %s; ln -sf ../../../../devel/sage/build/sage .'%SITE_PACKAGES)
+-
+ # search for dependencies and add to gcc -I<path>
+ include_dirs = ['%s/include'%SAGE_LOCAL,
+-                '%s/include/csage'%SAGE_LOCAL,
++                'c_lib/include',
+                 '%s/sage/sage/ext'%SAGE_DEVEL]
+ 
+ # search for dependencies only
+@@ -173,11 +170,11 @@ for m in ext_modules:
+ 
+     # FIMXE: Do NOT link the following libraries to each and
+     #        every module (regardless of the language btw.):
+-    m.libraries = ['csage'] + m.libraries + ['stdc++', 'ntl']
++    m.libraries = ['csage'] + m.libraries + ['stdc++', 'ntl', 'gmp', 'm', 'dl']
+ 
+     m.extra_compile_args += extra_compile_args
+     m.extra_link_args += extra_link_args
+-    m.library_dirs += ['%s/lib' % SAGE_LOCAL]
++    m.library_dirs += ['c_lib', '%s/lib' % SAGE_LOCAL]
+ 
+ 
+ 
+@@ -507,8 +504,8 @@ class sage_build_ext(build_ext):
+ #############################################
+ 
+ CYTHON_INCLUDE_DIRS=[
+-    SAGE_LOCAL + '/lib/python/site-packages/Cython/Includes/',
+-    SAGE_LOCAL + '/lib/python/site-packages/Cython/Includes/Deprecated/',
++    SAGE_LOCAL + '/lib/python2.7/site-packages/Cython/Includes/',
++    SAGE_LOCAL + '/lib/python2.7/site-packages/Cython/Includes/Deprecated/',
+ ]
+ 
+ # matches any dependency
+@@ -534,7 +531,7 @@ class DependencyTree:
+         self._timestamps = {}
+         self._deps = {}
+         self._deps_all = {}
+-        self.root = "%s/devel/sage/" % SAGE_ROOT
++        self.root = "%s/devel/sage" % SAGE_ROOT
+ 
+     def __getstate__(self):
+         """
+@@ -555,7 +552,7 @@ class DependencyTree:
+         self.__dict__.update(state)
+         self._timestamps = {}
+         self._deps_all = {}
+-        self.root = "%s/devel/sage/" % SAGE_ROOT
++        self.root = "%s/devel/sage" % SAGE_ROOT
+ 
+     def timestamp(self, filename):
+         """
+@@ -642,11 +639,8 @@ class DependencyTree:
+                 # so we really couldn't find the dependency -- raise
+                 # an exception. 
+                 if not found_include:
+-                    msg = 'could not find dependency %s included in %s.'%(path, filename)
+-                    if is_cython_file(path):
+-                        raise IOError, msg
+-                    else:
+-                        warnings.warn(msg+' I will assume it is a system C/C++ header.')
++                    if path[-2:] != '.h' and path[-4:] != '.hpp' and path[-4:] != '.pxd':  # there are implicit headers from distutils, etc
++                        raise IOError, "could not find dependency %s included in %s."%(path, filename)
+         f.close()
+         return list(deps)
+ 
+@@ -738,6 +732,10 @@ def compile_command0(p):
+             outfile += ".c"
+             cplus = ''
+ 
++        # speed up if doing an incremental builds
++        if os.path.exists(outfile) and os.path.getmtime(outfile) > os.path.getmtime(f):
++            return 0
++
+         if os.environ.get('SAGE_DEBUG', None)=='no':
+             debug = ''
+         else:
+@@ -750,7 +748,7 @@ def compile_command0(p):
+             return r
+ 
+         # if cython worked, copy the file to the build directory
+-        pyx_inst_file = '%s/%s'%(SITE_PACKAGES, f)
++        pyx_inst_file = '%s%s/%s'%(DESTDIR, SITE_PACKAGES, f)
+         retval = os.system('cp %s %s 2>/dev/null'%(f, pyx_inst_file))
+         # we could do this more elegantly -- load the files, use
+         # os.path.exists to check that they exist, etc. ... but the
diff --git a/sagemath-sagedoc.patch b/sagemath-sagedoc.patch
new file mode 100644
index 0000000..cad6ade
--- /dev/null
+++ b/sagemath-sagedoc.patch
@@ -0,0 +1,80 @@
+diff -up sage-5.8/spkg/build/sage-5.8/doc/common/builder.py.orig sage-5.8/spkg/build/sage-5.8/doc/common/builder.py
+--- sage-5.8/spkg/build/sage-5.8/doc/common/builder.py.orig	2013-03-19 16:06:49.142694873 -0300
++++ sage-5.8/spkg/build/sage-5.8/doc/common/builder.py	2013-03-19 16:07:08.156695601 -0300
+@@ -31,7 +31,7 @@ from sage.misc.misc import sage_makedirs
+ #     SAGE_DOC, LANGUAGES, SPHINXOPTS, PAPER, OMIT,
+ #     PAPEROPTS, ALLSPHINXOPTS, NUM_THREADS, WEBSITESPHINXOPTS
+ # from build_options.py.
+-execfile(os.path.join(os.getenv('SAGE_ROOT'), 'devel', 'sage', 'doc', 'common' , 'build_options.py'))
++execfile(os.path.join(os.getenv('SAGE_ROOT'), 'devel', 'doc', 'common' , 'build_options.py'))
+ 
+ 
+ ##########################################
+diff -up sage-5.8/spkg/build/sage-5.8/doc/common/conf.py.orig sage-5.8/spkg/build/sage-5.8/doc/common/conf.py
+--- sage-5.8/spkg/build/sage-5.8/doc/common/conf.py.orig	2013-03-19 16:07:24.854696241 -0300
++++ sage-5.8/spkg/build/sage-5.8/doc/common/conf.py	2013-03-19 16:08:21.261698401 -0300
+@@ -1,7 +1,7 @@
+ import sys, os, sphinx
+ 
+-SAGE_ROOT = os.environ['SAGE_ROOT']
+-SAGE_DOC = os.path.join(SAGE_ROOT, 'devel/sage/doc')
++SAGE_DEVEL = os.environ['SAGE_DEVEL']
++SAGE_DOC = os.environ['SAGE_DOC']
+ 
+ def get_doc_abspath(path):
+     """
+@@ -204,8 +204,7 @@ if (os.environ.get('SAGE_DOC_MATHJAX', '
+     from sage.misc.latex_macros import sage_mathjax_macros
+     html_theme_options['mathjax_macros'] = sage_mathjax_macros()
+ 
+-    from pkg_resources import Requirement, working_set
+-    sagenb_path = working_set.find(Requirement.parse('sagenb')).location
++    sagenb_path = SAGE_DEVEL
+     mathjax_relative = os.path.join('sagenb','data','mathjax')
+ 
+     # It would be really nice if sphinx would copy the entire mathjax directory,
+diff -up sage-5.8/spkg/build/sage-5.8/sage/interfaces/singular.py.orig sage-5.8/spkg/build/sage-5.8/sage/interfaces/singular.py
+--- sage-5.8/spkg/build/sage-5.8/sage/interfaces/singular.py.orig	2013-03-19 16:08:38.847699074 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/interfaces/singular.py	2013-03-19 16:08:52.885699612 -0300
+@@ -2144,7 +2144,7 @@ def generate_docstring_dictionary():
+     nodes.clear()
+     node_names.clear()
+ 
+-    singular_docdir = os.environ["SAGE_LOCAL"]+"/share/singular/"
++    singular_docdir = os.environ["SINGULAR_BIN_DIR"]+"/info/"
+ 
+     new_node = re.compile("File: singular\.hlp,  Node: ([^,]*),.*")
+     new_lookup = re.compile("\* ([^:]*):*([^.]*)\..*")
+diff -up sage-5.8/spkg/build/sage-5.8/sage/misc/latex_macros.py.orig sage-5.8/spkg/build/sage-5.8/sage/misc/latex_macros.py
+--- sage-5.8/spkg/build/sage-5.8/sage/misc/latex_macros.py.orig	2013-03-19 16:09:05.806700107 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/misc/latex_macros.py	2013-03-19 16:09:20.564700672 -0300
+@@ -142,7 +142,7 @@ def convert_latex_macro_to_mathjax(macro
+         return name + ': ["' + defn + '",' + str(num_args) + ']'
+ 
+ from superseded import deprecated_function_alias
+-convert_latex_macro_to_jsmath = deprecated_function_alias(13508, convert_latex_macro_to_mathjax)
++convert_latex_macro_to_jsmath = convert_latex_macro_to_mathjax
+ 
+ # To add a new macro for use in the Sage documentation, add a list or
+ # tuple to the following list.  Each list (or tuple) should have the
+diff -up sage-5.8/spkg/build/sage-5.8/sage/misc/sagedoc.py.orig sage-5.8/spkg/build/sage-5.8/sage/misc/sagedoc.py
+--- sage-5.8/spkg/build/sage-5.8/sage/misc/sagedoc.py.orig	2013-03-19 16:09:31.254701081 -0300
++++ sage-5.8/spkg/build/sage-5.8/sage/misc/sagedoc.py	2013-03-19 16:10:05.277702384 -0300
+@@ -704,13 +704,13 @@ def _search_src_or_doc(what, string, ext
+         module = ''
+         exts = ['html']
+         title = 'Documentation'
+-        base_path = os.path.join('devel', 'sage', 'doc', 'output')
+-        doc_path = os.path.join(ROOT, 'devel', 'sage', 'doc')
++        base_path = os.path.join('devel', 'output')
++        doc_path = os.path.join(ROOT, 'devel', 'doc')
+ 
+-        # We need to import stuff from SAGE_ROOT/devel/sage/doc/common
++        # We need to import stuff from SAGE_ROOT/devel/doc/common
+         # To do this, we temporarily change sys.path
+         oldpath = sys.path
+-        sys.path = oldpath + [os.path.join(ROOT, 'devel', 'sage', 'doc', 'common')]
++        sys.path = oldpath + [os.path.join(ROOT, 'devel', 'doc', 'common')]
+         import build_options as builder
+         # List of languages
+         lang = builder.LANGUAGES
diff --git a/sagemath-sagenb.patch b/sagemath-sagenb.patch
new file mode 100644
index 0000000..045f821
--- /dev/null
+++ b/sagemath-sagenb.patch
@@ -0,0 +1,72 @@
+diff -up sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/flask_version/base.py.orig sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/flask_version/base.py
+--- sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/flask_version/base.py.orig	2012-10-20 11:29:36.315150735 -0300
++++ sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/flask_version/base.py	2012-10-20 11:29:56.569151510 -0300
+@@ -27,7 +27,7 @@ class SageNBFlask(Flask):
+         self.add_static_path('/javascript', DATA)
+         self.add_static_path('/static', DATA)
+         self.add_static_path('/java', DATA)
+-        self.add_static_path('/java/jmol', os.path.join(os.environ["SAGE_ROOT"],"local","share","jmol"))
++        self.add_static_path('/java/jmol', os.path.join(DATA, "jmol"))
+         import mimetypes
+         mimetypes.add_type('text/plain','.jmol')
+ 
+diff -up sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/data/sage/html/notebook/base.html.orig sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/data/sage/html/notebook/base.html
+--- sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/data/sage/html/notebook/base.html.orig	2012-10-20 11:31:17.315154602 -0300
++++ sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/data/sage/html/notebook/base.html	2012-10-20 11:31:41.764155539 -0300
+@@ -69,7 +69,7 @@ INPUT:
+ <!-- Jmol - embedded 3D graphics -->
+ <script type="text/javascript" src="/java/jmol/appletweb/Jmol.js"></script>
+ <!-- This must stay in head -->
+-<script>jmolInitialize("/java/jmol");jmolSetCallback("menuFile","/java/jmol/appletweb/SageMenu.mnu");</script>
++<script>jmolInitialize("/java/jmol", "JmolApplet.jar,vecmath.jar");</script>
+ 
+ {% if JEDITABLE_TINYMCE and not worksheet.docbrowser() and not worksheet.is_published() %}
+ <!-- TinyMCE and jEditable - in-place editing of text cells -->
+diff -up sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/notebook/cell.py.orig sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/notebook/cell.py
+--- sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/notebook/cell.py.orig	2012-10-20 11:33:00.483158553 -0300
++++ sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/notebook/cell.py	2012-10-20 11:33:17.700159212 -0300
+@@ -2367,7 +2367,7 @@ class Cell(Cell_generic):
+                     jmol_script = jmol_file.read()
+                     jmol_file.close()
+ 
+-                    jmol_script = jmol_script.replace('defaultdirectory "', 'defaultdirectory "' + self.url_to_self() + '/')
++                    jmol_script = jmol_script.replace('defaultdirectory "', 'defaultdirectory "/home/' + self.worksheet_filename() + '/')
+ 
+                     jmol_file = open(jmol_name, 'w')
+                     jmol_file.write(jmol_script)
+diff -up sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/notebook/run_notebook.py.orig sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/notebook/run_notebook.py
+--- sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/notebook/run_notebook.py.orig	2012-10-20 11:31:55.106156049 -0300
++++ sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/notebook/run_notebook.py	2012-10-20 11:32:51.460158207 -0300
+@@ -46,15 +46,14 @@ sagenb.notebook.misc.DIR = %(cwd)r #We s
+ # Flask #
+ #########
+ import os, sys, random
+-flask_dir = os.path.join(os.environ['SAGE_ROOT'], 'devel', 'sagenb', 'flask_version')
+-sys.path.append(flask_dir)
+-import base as flask_base
++sagenb_dir = os.path.join(os.environ['SAGE_ROOT'], 'devel', 'sagenb')
++sys.path.append(sagenb_dir)
++import flask_version.base as flask_base
+ opts={}
+ startup_token = '{0:x}'.format(random.randint(0, 2**128))
+ if %(automatic_login)s:
+     opts['startup_token'] = startup_token
+-flask_app = flask_base.create_app(%(notebook_opts)s, **opts)
+-sys.path.remove(flask_dir)
++flask_app = flask_base.create_app(%(notebook_opts)s, startup_token=startup_token)
+ 
+ def save_notebook(notebook):
+     print "Quitting all running worksheets..."
+diff -up sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/data/sage/js/jmol_lib.js.orig sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/data/sage/js/jmol_lib.js
+--- sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/data/sage/js/jmol_lib.js.orig	2012-11-14 22:46:56.488853512 -0200
++++ sage-5.8/spkg/build/sagenb-0.10.4/src/sagenb/sagenb/data/sage/js/jmol_lib.js	2012-11-14 22:49:02.772858348 -0200
+@@ -256,9 +256,6 @@ function makeCntrlPanels(url, n, functio
+     panelHTML +='<button title="Move to own window" onClick="javascript:void(jmol_popup(\''+n+'\'))">Move to own window</button> arbitrarily resizable.<hr/>';
+     //static image to save
+     panelHTML +='<button onClick="sleepJmol('+n+',jmolStatus)"> Get Static Image to Save (Sleep) </button> Right-click or Cmd-click on image to get download options.<hr/>';
+-    //save file to local disk
+-    panelHTML += '<button title="Download View" onClick="javascript:void(jmolFileDownload('+n+'))">Download this view</button> will require loading signed applet if not already done.';
+-    panelHTML +='<hr/>';
+     //spin on
+     panelHTML +='<input class="worksheet" type="checkbox" value="spin on" onchange="jmol_spin(this.checked,'+n+');" title="Enable/disable spin"/>Spin on';
+     //antialaisdisplay (smoothing of objects)
diff --git a/sagemath-scons.patch b/sagemath-scons.patch
new file mode 100644
index 0000000..45a11e0
--- /dev/null
+++ b/sagemath-scons.patch
@@ -0,0 +1,39 @@
+diff -up sage-5.8/spkg/build/sage-5.8/c_lib/SConstruct.orig sage-5.8/spkg/build/sage-5.8/c_lib/SConstruct
+--- sage-5.8/spkg/build/sage-5.8/c_lib/SConstruct.orig	2013-02-23 12:55:48.382841120 -0300
++++ sage-5.8/spkg/build/sage-5.8/c_lib/SConstruct	2013-02-23 12:56:25.037842523 -0300
+@@ -126,18 +126,31 @@ env['PYV']=platform.python_version().rsp
+ # The SCons convenience function Split is the only strange thing 
+ # to python programmers. It just makes a list by splitting on 
+ # whitespace without the syntax clutter of lists of strings.
+-includes = ['$SAGE_LOCAL/include/', '$SAGE_LOCAL/include/python$PYV/',
+-            '$SAGE_LOCAL/include/NTL/', 'include']
++includes = ['@@includedir@@', '@@includedir@@/python$PYV/',
++            '@@includedir@@/NTL/', 'include']
+ cFiles = Split( "convert.c  interrupt.c  memory.c  mpn_pylong.c  mpz_pylong.c") + \
+          Split( "mpz_longlong.c stdsage.c  gmp_globals.c" )
+ cppFiles = Split( "ZZ_pylong.cpp  ntl_wrap.cpp" )
+ srcFiles = cFiles + cppFiles
+ 
++env.Append(CFLAGS='@@optflags@@')
++env.Append(CXXFLAGS='@@optflags@@')
++env.Append(LINKFLAGS='@@__global_ldflags@@')
++
++libname = "libcsage"
++major = "0"
++shlib_suffix = '.so.' + major
++shlink_flags = [ '@@__global_ldflags@@', '-shared', '-fPIC' ]
++soname = libname + shlib_suffix
++shlink_flags += [ '-Wl,-Bsymbolic', '-Wl,-soname=%s' % soname ]
++
+ lib = env.SharedLibrary( "csage", [ "src/" + x for x in srcFiles ],
+                          LIBS=['ntl', 'pari', 'gmp', 'python$PYV'], 
+-                         LIBPATH=['$SAGE_LOCAL/lib','$SAGE_LOCAL/lib/python$PYV/config/'],
++                         LIBPATH=['@@libdir@@','@@libdir@@/python$PYV/config/'],
++                         SHLIBSUFFIX=shlib_suffix,
++                         SHLINKFLAGS=shlink_flags,
+                          CPPPATH=includes )
+-env.Install("$SAGE_LOCAL/lib", lib)
++env.Install("@@libdir@@", lib)
+ 
+ #Here we only copy the files over if we are on Cygwin.  Otherwise, the
+ #library will be handled by the symlinks created in
diff --git a/sagemath-scripts.patch b/sagemath-scripts.patch
new file mode 100644
index 0000000..bb9b6ca
--- /dev/null
+++ b/sagemath-scripts.patch
@@ -0,0 +1,783 @@
+diff -up sage-5.8/spkg/bin/sage.orig sage-5.8/spkg/bin/sage
+--- sage-5.8/spkg/bin/sage.orig	2013-02-22 17:09:59.465820327 -0300
++++ sage-5.8/spkg/bin/sage	2013-02-22 17:17:23.824837343 -0300
+@@ -11,17 +11,14 @@ usage() {
+     echo "  file.<sage|py|spyx> -- run given .sage, .py or .spyx files"
+     echo "  -advanced           -- list all command line options"
+     echo "  -c <cmd>            -- Evaluates cmd as sage code"
+-    echo "  -experimental       -- list all experimental packages that can be installed"
+     echo "  -gap [...]          -- run Sage's Gap with given arguments"
+     echo "  -gp [...]           -- run Sage's PARI/GP calculator with given arguments"
+     echo "  -h, -?              -- print this help message"
+-    echo "  -i [packages]       -- install the given Sage packages"
+     echo "  -inotebook [...]    -- start the *insecure* Sage notebook"
+     echo "  -maxima [...]       -- run Sage's Maxima with given arguments"
+     echo "  -mwrank [...]       -- run Sage's mwrank with given arguments"
+     echo "  -n, -notebook [...] -- start the Sage notebook (options are the same"
+     echo "                         as for the notebook command in Sage)"
+-    echo "  -optional           -- list all optional packages that can be installed"
+     echo "  -python [...]       -- run the Python interpreter"
+     echo "  -R [...]            -- run Sage's R with given arguments"
+     echo "  -singular [...]     -- run Sage's singular with given arguments"
+@@ -38,10 +35,8 @@ usage() {
+     echo "                           -only-optional <tag1,...,tagn>  -- only run tests"
+     echo "                            including one of the #optional tags"
+     echo "                           -randorder[=seed]  -- randomize order of tests"
+-    echo "  -upgrade [url]      -- download, build and install standard packages from"
+-    echo "                         given url.  If url not given, automatically selects a"
+-    echo "                         suitable mirror.  If url='ask', it lets you select"
+-    echo "                         the mirror (uses SAGE_SERVER as default)."
++    echo "  -testall [options]  -- test all source files, docs, and examples.  options"
++    echo "                         like -t"
+     echo "  -v, -version        -- print the Sage version"
+     exit 0
+ }
+@@ -71,8 +66,6 @@ usage_advanced() {
+     ####  1.......................26..................................................78
+     ####  |.....................--.|...................................................|
+     echo "Running the notebook:"
+-    echo "  -bn, -build-and-notebook [...] -- build the Sage library then start"
+-    echo "                         the Sage notebook"
+     echo "  -inotebook [...]    -- start the *insecure* Sage notebook"
+     echo "  -n, -notebook [...] -- start the Sage notebook (options are the same"
+     echo "                         as for the notebook command in Sage)"
+@@ -90,13 +83,8 @@ usage_advanced() {
+     echo "  -hg [...]           -- run Sage's Mercurial with given arguments"
+     echo "  -ipython [...]      -- run Sage's IPython using the default environment (not"
+     echo "                         Sage), passing additional options to IPython"
+-    echo "  -kash [...]         -- run Sage's Kash with given arguments"
+-    test -x "$SAGE_LOCAL/bin/kash" || \
+-    echo "                         (not installed currently, run sage -i kash)"
+     echo "  -lisp [...]         -- run Lisp interpreter included with Sage"
+     echo "  -M2 [...]           -- run Sage's Macaulay2 with given arguments"
+-    test -x "$SAGE_LOCAL/bin/M2" || \
+-    echo "                         (not installed currently, run sage -i macaulay2)"
+     echo "  -maxima [...]       -- run Sage's Maxima with given arguments"
+     echo "  -mwrank [...]       -- run Sage's mwrank with given arguments"
+     echo "  -python [...]       -- run the Python interpreter"
+@@ -110,77 +98,10 @@ usage_advanced() {
+     echo
+     ####  1.......................26..................................................78
+     ####  |.....................--.|...................................................|
+-    echo "Installing packages and upgrading:"
+-    echo "  -experimental       -- list all experimental packages that can be installed"
+-    echo "  -f [opts] [packages]-- shortcut for -i -f: force build of the given Sage"
+-    echo "                         packages"
+-    echo "  -i [opts] [packages]-- install the given Sage packages (unless they are"
+-    echo "                         already installed); if no packages are given, print"
+-    echo "                         a list of all installed packages.  Options:"
+-    echo "                           -c -- run the packages' test suites"
+-    echo "                           -f -- force build: install the packages even"
+-    echo "                                 if they are already installed"
+-    echo "                           -s -- do not delete the spkg/build directories"
+-    echo "                                 after a successful build"
+-    echo "  -info [packages]    -- print the SPKG.txt of the given packages"
+-    echo "  -optional           -- list all optional packages that can be installed"
+-    echo "  -standard           -- list all standard packages that can be installed"
+-   #echo "  -update             -- download latest non-optional Sage packages (do not build them)"
+-   #echo "  -update-build       -- build and install all downloaded non-optional Sage packages"
+-    echo "  -upgrade [url]      -- download, build and install standard packages from"
+-    echo "                         given url.  If url not given, automatically selects a"
+-    echo "                         suitable mirror.  If url='ask', it lets you select"
+-    echo "                         the mirror (uses SAGE_SERVER as default)."
+-
+-    echo
+-    ####  1.......................26..................................................78
+-    ####  |.....................--.|...................................................|
+-    echo "Building and testing the Sage library:"
+-    echo "  -b [branch]         -- build Sage library.  If branch is given, switch to"
+-    echo "                         branch in devel/sage-branch and build that branch"
+-    echo "  -sync-build         -- delete old code and other files in the Sage library"
+-    echo "                         that have already been deleted from devel/sage but"
+-    echo "                         remain in the build directory.  This is sometimes"
+-    echo "                         necessary because \`sage -b\` merely copies new or"
+-    echo "                         modified files to the target directory."
+-    echo "  -ba [branch]        -- same as -b and rebuild all Cython code"
+-    echo "  -ba-force [branch]  -- same as -ba, but don't query before rebuilding"
+-    echo "  -br [branch]        -- switch to, build, and run Sage given branch"
+-    echo "  -branch             -- print the current Sage branch"
+-    echo "  -bt [...]           -- build and test, options like -t below"
+-    echo "  -btp <N> [...]      -- build and test parallel, options like -tp below"
+-    echo "  -btnew [...]        -- build and test modified files, options like -tnew"
+-    echo "  -clone [new branch] -- clone a new branch of the Sage library from the"
+-    echo "                         current branch"
+-    echo "  -fixdoctests <file.py> -- create <file.py>.out that would pass the doctests"
+-    echo "                            and output a patch"
+-    echo "  -startuptime [module]  -- display how long each component of Sage takes to"
+-    echo "                            start up; optionally specify a module to get more"
+-    echo "                            details about that particular module"
+-    echo "  -t [options] <files|dir>"
+-    echo "                      -- test examples in .py, .pyx, .sage or .tex files"
+-    echo "                         options:"
+-    echo "                           -long  -- include lines with the phrase 'long time'"
+-    echo "                           -verbose  -- print debugging output during the test"
+-    echo "                           -optional  -- also test all #optional examples"
+-    echo "                           -only-optional <tag1,...,tagn>  -- only run tests"
+-    echo "                            including one of the #optional tags"
+-    echo "                           -randorder[=seed]  -- randomize order of tests"
+-    echo "  -tnew [...]         -- like -t above, but only tests files modified since"
+-    echo "                         last commit"
+-    echo "  -tp <N> [...]       -- like -t above, but tests in parallel using N threads"
+-    echo "                         with 0 interpreted as a sensible default"
+-    echo "  -testall [options]  -- test all source files, docs, and examples.  options"
+-    echo "                         like -t"
+-
+-    echo
+-    ####  1.......................26..................................................78
+-    ####  |.....................--.|...................................................|
+     echo "Documentation:"
+     echo "  -coverage <files>   -- give info about doctest coverage of files"
+     echo "  -coverageall        -- give summary info about doctest coverage of all"
+     echo "                         files in the Sage library"
+-    echo "  -docbuild [lang/]<document> <html|pdf|...> -- Build the Sage documentation"
+     echo "  -search_src <string> -- search through all the Sage library code for string"
+     echo "  -search_doc <string> -- search through the Sage documentation for string"
+     echo "  -grep <string>      -- same as -search_src"
+@@ -198,20 +119,6 @@ usage_advanced() {
+     echo
+     ####  1.......................26..................................................78
+     ####  |.....................--.|...................................................|
+-    echo "Making Sage packages or distributions:"
+-    echo "  -bdist VER          -- build a binary distribution of Sage"
+-    echo "  -combinat [...]     -- run sage-combinat patch management script"
+-    echo "  -crap sage-ver.tar  -- detect suspicious garbage in sage source tarball"
+-    echo "  -merge              -- run Sage's automatic merge and test script"
+-    echo "  -pkg <dir>          -- create Sage package dir.spkg from a given directory"
+-    echo "  -pkg_nc <dir>       -- as -pkg, but do not compress the package"
+-    echo "  -rsyncdist VER      -- build an rsyncable source distribution of Sage (you"
+-    echo "                         must first run sage -sdist VER for this to work)"
+-    echo "  -sdist VER          -- build a source distribution of Sage"
+-
+-    echo
+-    ####  1.......................26..................................................78
+-    ####  |.....................--.|...................................................|
+     echo "Valgrind memory debugging:"
+     echo "  -cachegrind         -- run Sage using Valgrind's cachegrind tool.  The log"
+     echo "                         files are named sage-cachegrind.PID can be found in"
+@@ -225,9 +132,6 @@ usage_advanced() {
+     echo "  -memcheck           -- run Sage using Valgrind's memcheck tool.  The log"
+     echo "                         files are named sage-memcheck.PID can be found in"
+     echo "                         $DOT_SAGE"
+-    echo "  -omega              -- run Sage using Valgrind's omega tool.  The log"
+-    echo "                         files are named sage-omega.PID can be found in"
+-    echo "                         $DOT_SAGE"
+     echo "  -valgrind           -- this is an alias for -memcheck"
+     echo
+     echo "You can also use -- before a long option, e.g., 'sage --optional'."
+@@ -247,15 +151,6 @@ if [ "$1" = '--nodotsage' ]; then
+     exit $status
+ fi
+ 
+-# Make sure this doesn't produce output (in case we use this in scripts).
+-. "$SAGE_ROOT/spkg/bin/sage-env" >&2
+-if [ $? -ne 0 ]; then
+-    echo >&2 "Error setting environment variables by sourcing '$SAGE_ROOT/spkg/bin/sage-env';"
+-    echo >&2 "possibly contact sage-devel (see http://groups.google.com/group/sage-devel)."
+-    exit 1
+-fi
+-
+-
+ if [ $# -gt 0 ]; then
+   if [ "$1" = '-h' -o "$1" = '-?' -o "$1" = '-help' -o "$1" = '--help' ]; then
+      usage
+@@ -268,30 +163,11 @@ fi
+ 
+ # Prepare for running Sage, either interactively or non-interactively.
+ sage_setup() {
+-    # Check that we're not in a source tarball which hasn't been built yet (#13561).
+-    if [ ! -d "$SAGE_LOCAL/lib/python/site-packages/sage" ]; then
+-        echo >&2 '************************************************************************'
+-        echo >&2 'It seems that you are attempting to run Sage from an unpacked source'
+-        echo >&2 'tarball, but you have not compiled it yet (or maybe the build has not'
+-        echo >&2 'finished). You should run `make` in the Sage root directory first.'
+-        echo >&2 'If you did not intend to build Sage from source, you should download'
+-        echo >&2 'a binary tarball instead. Read README.txt for more information.'
+-        echo >&2 '************************************************************************'
+-        exit 1
+-    fi
+-
+     # Display the startup banner
+     if [ "$SAGE_BANNER" != "no" ]; then
+         cat "$SAGE_LOCAL/bin/sage-banner"
+     fi
+ 
+-    # Check to see if the whole Sage install tree has moved.  If so,
+-    # change various hardcoded paths.  Skip this if we don't have write
+-    # access to $SAGE_LOCAL (e.g. when running as a different user).
+-    if [ -w "$SAGE_LOCAL" ]; then
+-        sage-location || exit $?
+-    fi
+-
+     if [ ! -d "$IPYTHONDIR" ]; then
+         # make sure that $DOT_SAGE exists so that ipython will happily
+         # create its config directories there.  If DOT_SAGE doesn't
+@@ -340,12 +216,6 @@ if [ "$1" = '-root'  -o "$1" = '--root'
+     exit 0
+ fi
+ 
+-if [ "$1" = '-branch'  -o "$1" = '--branch' ]; then
+-    cd "$SAGE_ROOT/devel/sage"
+-    pwd -P | sed 's|.*/||; s|^sage-||'
+-    exit $?
+-fi
+-
+ #####################################################################
+ # Run Sage's versions of the standard Algebra/Geometry etc. software
+ #####################################################################
+@@ -355,74 +225,59 @@ if [ "$1" = '-axiom' -o "$1" = '--axiom'
+     exec axiom "$@"
+ fi
+ 
+-if [ "$1" = '-combinat' -o "$1" = '--combinat' ]; then
+-    shift
+-    exec sage-combinat "$@"
+-fi
+-
+ if [ "$1" = '-gap' -o "$1" = '--gap' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/gap" "$@"
++    exec gap "$@"
+ fi
+ 
+ if [ "$1" = '-gp' -o "$1" = '--gp' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/gp" "$@"
++    exec gp "$@"
+ fi
+ 
+ if [ "$1" = '-singular' -o "$1" = '--singular' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/singular" "$@"
++    exec singular "$@"
+ fi
+ 
+ if [ "$1" = '-sqlite3' -o "$1" = '--sqlite3' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/sqlite3" "$@"
++    exec sqlite3 "$@"
+ fi
+ 
+ if [ "$1" = '-twistd' -o "$1" = '--twistd' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/twistd" "$@"
++    exec twistd "$@"
+ fi
+ 
+ if [ "$1" = '-ecl' -o "$1" = '--ecl' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/ecl" "$@"
++    exec ecl "$@"
+ fi
+ 
+ if [ "$1" = '-lisp' -o "$1" = '--lisp' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/ecl" "$@"
+-fi
+-
+-if [ "$1" = '-kash' -o "$1" = '--kash' ]; then
+-    shift
+-    exec "$SAGE_LOCAL/bin/kash" "$@"
+-fi
+-
+-if [ "$1" = '-fixdoctests' -o "$1" = '--fixdoctests' ]; then
+-    shift
+-    exec sage-fixdoctests "$@"
++    exec ecl "$@"
+ fi
+ 
+ if [ "$1" = '-maxima' -o "$1" = '--maxima' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/maxima" "$@"
++    exec maxima "$@"
+ fi
+ 
+ if [ "$1" = '-mwrank' -o "$1" = '--mwrank' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/mwrank" "$@"
++    exec mwrank "$@"
+ fi
+ 
+ if [ "$1" = '-M2' -o "$1" = '--M2' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/M2" "$@"
++    exec M2 "$@"
+ fi
+ 
+ if [ "$1" = '-scons' -o "$1" = '--scons' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/scons" "$@"
++    exec scons "$@"
+ fi
+ 
+ if [ "$1" = '-python' -o "$1" = '--python' ]; then
+@@ -432,12 +287,12 @@ fi
+ 
+ if [ "$1" = '-R' -o "$1" = '--R' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/R" "$@"
++    exec R "$@"
+ fi
+ 
+ if [ "$1" = '-ipython' -o "$1" = '--ipython' ]; then
+     shift
+-    exec "$SAGE_LOCAL/bin/ipython" "$@"
++    exec ipython "$@"
+ fi
+ 
+ if [ "$1" = '-sh' -o "$1" = '--sh' ]; then
+@@ -558,33 +413,6 @@ EOF
+     exit $status
+ fi
+ 
+-if [ "$1" = '-hg' -o "$1" = '--hg' ]; then
+-    shift
+-    # Disable HGPLAIN, so we use all user defaults
+-    # (both in $SAGE_LOCAL/etc/mercurial and $HOME/.hgrc)
+-    unset HGPLAIN
+-    exec "$SAGE_LOCAL/bin/hg" "$@"
+-fi
+-
+-if [ "$1" = '-merge' -o "$1" = '--merge' ]; then
+-    shift
+-    exec sage-apply-ticket "$@"
+-fi
+-
+-#####################################################################
+-# Test coverage of a module?
+-#####################################################################
+-
+-if [ "$1" = "-coverage" -o "$1" = "--coverage" ]; then
+-    shift
+-    exec sage-coverage "$@"
+-fi
+-
+-if [ "$1" = "-coverageall" -o "$1" = "--coverageall" ]; then
+-    shift
+-    exec sage-coverageall "$@"
+-fi
+-
+ #####################################################################
+ # File conversion
+ #####################################################################
+@@ -600,35 +428,15 @@ if [ "$1" = '-rst2sws' -o "$1" = '--rst2
+ fi
+ 
+ #####################################################################
+-# Crap
+-#####################################################################
+-
+-if [ "$1" = "-crap" -o "$1" = "--crap" ]; then
+-    shift
+-    exec sage-crap $@
+-fi
+-
+-#####################################################################
+ # Run Sage's versions of the standard Algebra/Geometry etc. software
+ #####################################################################
+ 
+-build_sage() {
+-    sage-build "$@" || exit $?
+-}
+-
+ if [ "$1" = "-notebook" -o "$1" = '--notebook' -o "$1" = '-n' ]; then
+     shift
+     sage-cleaner &>/dev/null &
+     exec sage-notebook "$@"
+ fi
+ 
+-if [ "$1" = "-bn" -o "$1" = "--build-and-notebook" ]; then
+-    shift
+-    build_sage
+-    sage-cleaner &>/dev/null &
+-    exec sage-notebook "$@"
+-fi
+-
+ if [ "$1" = "-inotebook" -o "$1" = '--inotebook' ]; then
+     shift
+     sage-cleaner &>/dev/null &
+@@ -651,79 +459,7 @@ if [ "$1" = '-grepdoc' -o "$1" = "--grep
+    exit 0
+ fi
+ 
+-if [ "$1" = '-b' ]; then
+-    shift
+-    time build_sage "$@"
+-    exit $?
+-fi
+-
+-if [ "$1" = '-br' -o "$1" = "--br" ]; then
+-    shift
+-    build_sage "$@"
+-    interactive_sage
+-fi
+-
+-if [ "$1" = '-r' ]; then
+-   shift
+-   if [ "$1" != "" ]; then
+-      cd "$SAGE_ROOT/devel/"
+-      if [ ! -d "sage-$1" ]; then
+-         echo >&2 "No such branch '$SAGE_ROOT/devel/sage-$1'"
+-         echo >&2 "Use 'sage --clone' to create a new branch."
+-         exit 1
+-      fi
+-      # On Solaris (and perhaps other systems), "ln -snf FILE LINK"
+-      # doesn't remove LINK and then relink it, so we need to first
+-      # delete LINK -- in this case, SAGE_ROOT/devel/sage -- and then
+-      # create a new link.  We use the full path name to make sure we
+-      # remove the correct file.
+-      rm -f "$SAGE_ROOT/devel/sage"
+-      ln -s "sage-$1" sage
+-   fi
+-   interactive_sage
+-fi
+-
+-if [ "$1" = '-ba' ]; then
+-    shift
+-    echo " *** WARNING ***"
+-    echo " You are about to rebuild the entire Sage library."
+-    echo " This will take a significant amount of time."
+-    echo " (Use --ba-force instead of -ba to skip this prompt.)"
+-    echo -n " Do you want to proceed? [y/n] "
+-    read CHOICE
+-    while [ "$CHOICE" != "y" -a "$CHOICE" != "n" ]; do
+-        echo -n " Choose one of y, n: "
+-        read CHOICE
+-    done
+-    if [ $CHOICE = 'n' ]; then
+-        exit 0
+-    fi
+-    build_sage -b "$@"
+-    exit $?
+-fi
+-
+-if [ "$1" = '-ba-force' -o "$1" = '--ba-force' ]; then
+-    shift
+-    build_sage -b "$@"
+-    exit $?
+-fi
+-
+-if [ "$1" = '-sync-build' -o "$1" = '--sync-build' ]; then
+-    shift
+-    cd "$SAGE_ROOT"
+-    exec sage-sync-build.py "$@"
+-fi
+-
+-if [ "$1" = '-clone' -o "$1" = "--clone" ]; then
+-   shift
+-   time sage-clone "$@"
+-   exit $?
+-fi
+-
+-if [ "$1" = '-t' -o "$1" = '-bt' ]; then
+-   if [ "$1" = '-bt' ]; then
+-      build_sage
+-   fi
++if [ "$1" = '-t' ]; then
+    if ! [  -f  "$DOT_SAGE"/init.sage ]; then
+       echo >&2 "init.sage does not exist ... creating"
+       touch "$DOT_SAGE"/init.sage
+@@ -735,10 +471,7 @@ if [ "$1" = '-t' -o "$1" = '-bt' ]; then
+    exit $?
+ fi
+ 
+-if [ "$1" = '-tp' -o "$1" = '-btp' ]; then
+-   if [ "$1" = '-btp' ]; then
+-      build_sage
+-   fi
++if [ "$1" = '-tp' ]; then
+    if ! [  -f  "$DOT_SAGE"/init.sage ]; then
+       echo >&2 "init.sage does not exist ... creating"
+       touch "$DOT_SAGE"/init.sage
+@@ -750,10 +483,7 @@ if [ "$1" = '-tp' -o "$1" = '-btp' ]; th
+    exit $?
+ fi
+ 
+-if [ "$1" = '-tnew' -o "$1" = '-btnew' ]; then
+-   if [ "$1" = '-btnew' ]; then
+-      build_sage
+-   fi
++if [ "$1" = '-tnew' ]; then
+    shift
+    SAGE_BANNER="no"
+    sage_setup
+@@ -769,12 +499,6 @@ if [ "$1" = '-testall' -o "$1" = "--test
+    exit $?
+ fi
+ 
+-if [ "$1" = '-patchbot' -o "$1" = "--patchbot" ]; then
+-    shift
+-    cd "$SAGE_ROOT"
+-    exec "$SAGE_LOCAL/bin/patchbot/patchbot.py" "$@"
+-fi
+-
+ if [ "$1" = '-c' ]; then
+     shift
+     SAGE_BANNER="no"
+@@ -783,164 +507,6 @@ if [ "$1" = '-c' ]; then
+     exec sage-eval "$@"
+ fi
+ 
+-install() {
+-    mkdir -p "$SAGE_LOGS"
+-    for PKG in "$@"
+-    do
+-        # Check for options
+-        case "$PKG" in
+-            -f) OPTF="-f"
+-                continue;;
+-            -m) OPTS="-s"
+-                echo >&2 "Warning: the -m option is deprecated since Sage 5.0.  Use -s instead."
+-                continue;;
+-            -s) OPTS="-s"
+-                continue;;
+-            -c) OPTC="-c"
+-                continue;;
+-            --check) OPTC="-c"
+-                continue;;
+-            -info) OPTINFO="--info"
+-                continue;;
+-            --info) OPTINFO="--info"
+-                continue;;
+-            -*) echo >&2 "Error: unknown option '$PKG'"
+-                exit 2;;
+-        esac
+-
+-        PKG_NAME=`echo "$PKG" | sed -e "s/\.spkg$//"`
+-        PKG_NAME=`basename "$PKG_NAME"`
+-
+-        "$SAGE_ROOT"/spkg/pipestatus \
+-            "sage-spkg $OPTINFO $OPTF $OPTS $OPTC '$PKG' 2>&1" \
+-            "(trap '' SIGINT; tee -a '$SAGE_ROOT/install.log' '$SAGE_LOGS/$PKG_NAME.log')"
+-        # Do not try to install further packages if one failed
+-        if [ $? -ne 0 ]; then
+-            exit 1
+-        fi
+-    done
+-
+-    # Run sage-location to update paths of the package(s) we just
+-    # installed.
+-    exec sage-location
+-}
+-
+-if [ "$1" = '-optional' -o "$1" = "--optional" ]; then
+-    exec sage-list-optional
+-fi
+-
+-if [ "$1" = '-experimental' -o "$1" = "--experimental" ]; then
+-    exec sage-list-experimental
+-fi
+-
+-if [ "$1" = '-standard' -o "$1" = "--standard" ]; then
+-    exec sage-list-standard
+-fi
+-
+-if [ "$1" = '-i' ]; then
+-    shift
+-    # If there are no further arguments, simply list all installed
+-    # packages.
+-    if [ $# -eq 0 ]; then
+-        exec sage-spkg
+-    fi
+-    install "$@"
+-fi
+-
+-if [ "$1" = '-f' ]; then
+-    shift
+-    # If there are no further arguments, simply list all installed
+-    # packages.
+-    if [ $# -eq 0 ]; then
+-        exec sage-spkg
+-    fi
+-    install -f "$@"
+-fi
+-
+-if [ "$1" = '-info' -o "$1" = '--info' ]; then
+-    shift
+-    for PKG in "$@"
+-    do
+-        sage-spkg --info "$PKG" || exit $?
+-    done
+-    exit 0
+-fi
+-
+-if [ "$1" = '-pkg' -o "$1" = '-spkg' -o "$1" = "--pkg" -o "$1" = "--spkg" ]; then
+-    shift
+-    exec sage-pkg "$@"
+-fi
+-
+-if [ "$1" = '-pkg_nc' -o "$1" = "--pkg_nc" ]; then
+-    shift
+-    exec sage-pkg -n "$@"
+-fi
+-
+-if [ "$1" = '-sdist' -o "$1" = "--sdist" ]; then
+-    if [ $# -ne 2 ]; then
+-        echo >&2 "** MISSING VERSION NUMBER! **"
+-        exit 2
+-    fi
+-    exec sage-sdist $2 "$SAGE_ROOT"
+-fi
+-
+-if [ "$1" = '-rsyncdist' -o "$1" = "--rsyncdist" ]; then
+-    if [ $# -ne 2 ]; then
+-        echo >&2 "** MISSING VERSION NUMBER! **"
+-        exit 2
+-    fi
+-    exec sage-rsyncdist $2
+-fi
+-
+-if [ "$1" = '-bdist' -o "$1" = "--bdist" ]; then
+-    if [ $# -ne 2 ]; then
+-        echo >&2 "** MISSING VERSION NUMBER! **"
+-        exit 2
+-    fi
+-    cd "$SAGE_ROOT"
+-    exec sage-bdist $2 "$SAGE_ROOT"
+-fi
+-
+-#if [ "$1" = '-update' ]; then
+-#    sage-update
+-#    exit $?
+-#fi
+-
+-#if [ "$1" = '-update-build' -o "$1" = "--update-build" ]; then
+-#    sage-update-build
+-#    sage-update-build
+-#    exit $?
+-#fi
+-
+-if [ "$1" = '-upgrade' -o "$1" = "--upgrade" ]; then
+-    shift
+-    cd "$SAGE_ROOT"
+-
+-    # People often move the Sage install right before doing the upgrade, so it's
+-    # important to fix any path hardcoding issues first, or certain library
+-    # links will fail.
+-    sage-location || exit $?
+-
+-    # Run sage-upgrade twice since when installing sage-scripts and a
+-    # running script changes, it gets confused and exits with an error.
+-    # Running again (with the script replaced) then fixes the problem.
+-    sage-upgrade "$@"
+-    if [ $? -eq 2 ]; then   # this exit code means the user elected not to do the upgrade at all.
+-        exit 2
+-    fi
+-    echo "Double checking that all packages have been installed."
+-    sage-upgrade "$@" || exit $?
+-
+-    # Check that Sage still works
+-    sage-starts
+-    exit $?
+-fi
+-
+-if [ "$1" = "-docbuild" -o "$1" = "--docbuild" ]; then
+-    shift
+-    exec python "$SAGE_ROOT/devel/sage/doc/common/builder.py" "$@"
+-fi
+-
+ if [ "$1" = '-gdb' -o "$1" = "--gdb" ]; then
+     shift
+     sage_setup
+@@ -989,12 +555,6 @@ if [ "$1" = '-callgrind' -o "$1" = "--ca
+     exec sage-callgrind "$@"
+ fi
+ 
+-if [ "$1" = '-omega' -o "$1" = "--omega" ]; then
+-    shift
+-    sage_setup
+-    exec sage-omega "$@"
+-fi
+-
+ if [ "$1" = '-startuptime' -o "$1" = '--startuptime' ]; then
+     exec sage-startuptime.py "$@"
+ fi
+diff -up sage-5.8/spkg/build/sage_scripts-5.8/sage-doctest.orig sage-5.8/spkg/build/sage_scripts-5.8/sage-doctest
+--- sage-5.8/spkg/build/sage_scripts-5.8/sage-doctest.orig	2013-02-22 17:19:08.426841348 -0300
++++ sage-5.8/spkg/build/sage_scripts-5.8/sage-doctest	2013-02-22 17:20:08.600843653 -0300
+@@ -90,11 +90,6 @@ def delete_tmpfiles():
+ # Set environment variables
+ ######################################################    
+ SAGE_ROOT = os.environ["SAGE_ROOT"]
+-LD = os.environ["LD_LIBRARY_PATH"]
+-os.environ["LD_LIBRARY_PATH"] = os.path.join(SAGE_ROOT, 'local',
+-                                             'lib') + ":" + LD
+-os.environ["PYTHONPATH"] = os.path.join(SAGE_ROOT, 'local', 'lib', 'python',
+-                                        'site-packages')
+ if os.environ.has_key('SAGE_PATH'):
+     os.environ["PYTHONPATH"] = os.environ["PYTHONPATH"] + ':' + os.environ['SAGE_PATH']
+ 
+@@ -125,11 +120,6 @@ try:
+ except:
+     SAGE_CALLGRIND_FLAGS = logfile % 'cachegrind.%p'
+ 
+-try:
+-    SAGE_OMEGA_FLAGS = os.environ['SAGE_OMEGA_FLAGS']
+-except:
+-    SAGE_OMEGA_FLAGS = logfile % 'omega.%p'
+-
+ ######################################################
+ # The Python binary
+ ######################################################
+@@ -790,8 +780,6 @@ def test_file(file, library_code):
+             cmd = "valgrind --tool=massif " + SAGE_MASSIF_FLAGS + cmd
+         if cachegrind:
+             cmd = "valgrind --tool=cachegrind " +  SAGE_CACHEGRIND_FLAGS + cmd
+-        if omega:
+-            cmd = "valgrind --tool=exp-omega " + SAGE_OMEGA_FLAGS + cmd
+ 
+         VALGRIND = os.path.join(DOT_SAGE, 'valgrind')
+         try:
+@@ -945,13 +933,12 @@ if __name__ ==  '__main__':
+         memcheck   = has_opt('memcheck') or has_opt('valgrind')
+         massif     = has_opt('massif')
+         cachegrind = has_opt('cachegrind')
+-        omega      = has_opt('omega')
+         force_lib  = has_opt('force_lib')
+         random_order = parse_rand()
+         only_optional, only_optional_tags = parse_only_opt()
+         if long_time:
+             TIMEOUT = TIMEOUT_LONG
+-        if gdb or memcheck or massif or cachegrind or omega:
++        if gdb or memcheck or massif or cachegrind:
+             TIMEOUT = TIMEOUT_VALGRIND
+         if argv[1][0] == '-':
+             usage()
+@@ -959,7 +946,7 @@ if __name__ ==  '__main__':
+         ext = os.path.splitext(argv[1])[1]
+ 
+         library_code = True
+-        dev_path = os.path.realpath(os.path.join(SAGE_ROOT, 'devel'))
++        dev_path = os.path.realpath(os.environ['SAGE_DEVEL'] + '/sage')
+         our_path = os.path.realpath(argv[1])
+ 
+         if not force_lib and (ext in ['.spyx', '.sage'] or
+diff -up sage-5.8/spkg/build/sage_scripts-5.8/sage-maketest.orig sage-5.8/spkg/build/sage_scripts-5.8/sage-maketest
+--- sage-5.8/spkg/build/sage_scripts-5.8/sage-maketest.orig	2013-02-22 17:20:29.074844437 -0300
++++ sage-5.8/spkg/build/sage_scripts-5.8/sage-maketest	2013-02-22 17:20:51.800845307 -0300
+@@ -16,10 +16,10 @@ echo `date` >> "$SAGE_TEST_LOG"
+ # whose names consist of two lowercase letters: those should match the
+ # various languages.
+ 
+-"$SAGE_ROOT"/sage -t --sagenb "$@" \
+-    "$SAGE_ROOT"/devel/sage/doc/common \
+-    "$SAGE_ROOT"/devel/sage/doc/[a-z][a-z] \
+-    "$SAGE_ROOT"/devel/sage/sage 2>&1 | tee -a "$SAGE_TEST_LOG"
++sage -t --sagenb "$@" \
++    devel/sage/doc/common \
++    devel/sage/doc/[a-z][a-z] \
++    devel/sage/sage 2>&1 | tee -a "$SAGE_TEST_LOG"
+ 
+ if [ "$SAGE_TESTDIR" = "$SAGE_ROOT/tmp" ]; then
+     cat "$SAGE_TEST_LOG" >> "$SAGE_ROOT"/test.log
+diff -up sage-5.8/spkg/build/sage_scripts-5.8/sage-valgrind.orig sage-5.8/spkg/build/sage_scripts-5.8/sage-valgrind
+--- sage-5.8/spkg/build/sage_scripts-5.8/sage-valgrind.orig	2013-02-22 17:21:05.994845850 -0300
++++ sage-5.8/spkg/build/sage_scripts-5.8/sage-valgrind	2013-02-22 17:21:14.960846194 -0300
+@@ -11,7 +11,7 @@ fi
+ LOG="$DOT_SAGE"/valgrind/sage-memcheck.%p
+ echo "Log file is $LOG"
+ 
+-MEMCHECK_FLAGS="--leak-resolution=high --log-file=$LOG --leak-check=full --num-callers=25 --suppressions=$SAGE_LOCAL/lib/valgrind/sage.supp "; export MEMCHECK_FLAGS
++MEMCHECK_FLAGS="--leak-resolution=high --log-file=$LOG --leak-check=full --num-callers=25 "; export MEMCHECK_FLAGS
+ if [ "$SAGE_MEMCHECK_FLAGS" ]; then
+     echo "Overwriting memcheck flags with:"
+     echo $SAGE_MEMCHECK_FLAGS
diff --git a/sagemath-unpatched_ntl.patch b/sagemath-unpatched_ntl.patch
new file mode 100644
index 0000000..13e5526
--- /dev/null
+++ b/sagemath-unpatched_ntl.patch
@@ -0,0 +1,60 @@
+diff -up sage-5.8/spkg/build/sage-5.8/c_lib/include/ntl_wrap.h.orig sage-5.8/spkg/build/sage-5.8/c_lib/include/ntl_wrap.h
+--- sage-5.8/spkg/build/sage-5.8/c_lib/include/ntl_wrap.h.orig	2013-01-25 21:54:01.313110341 -0200
++++ sage-5.8/spkg/build/sage-5.8/c_lib/include/ntl_wrap.h	2013-01-25 21:54:13.153110794 -0200
+@@ -35,8 +35,6 @@ using namespace NTL;
+ 
+ EXTERN void del_charstar(char*);
+ 
+-EXTERN void setup_NTL_error_callback(void (*function)(const char*, void*), void* context);
+-
+ ////////  ZZ //////////
+ 
+ #ifndef __cplusplus
+diff -up sage-5.8/spkg/build/sage-5.8/c_lib/src/ntl_wrap.cpp.orig sage-5.8/spkg/build/sage-5.8/c_lib/src/ntl_wrap.cpp
+--- sage-5.8/spkg/build/sage-5.8/c_lib/src/ntl_wrap.cpp.orig	2013-01-25 21:53:32.800109249 -0200
++++ sage-5.8/spkg/build/sage-5.8/c_lib/src/ntl_wrap.cpp	2013-01-25 21:53:49.625109893 -0200
+@@ -11,13 +11,6 @@ void del_charstar(char* a) {
+     delete[] a;
+ }
+ 
+-
+-void setup_NTL_error_callback(void (*function)(const char*, void*), void* context)
+-{
+-    NTL::SetErrorCallbackFunction(function, context);
+-}
+-
+-
+ //////// ZZ //////////
+ 
+ /* Return value is only valid if the result should fit into an int.
+diff -up sage-5.8/spkg/build/sage-5.8/c_lib/src/stdsage.c.orig sage-5.8/spkg/build/sage-5.8/c_lib/src/stdsage.c
+--- sage-5.8/spkg/build/sage-5.8/c_lib/src/stdsage.c.orig	2013-01-25 21:54:34.072111596 -0200
++++ sage-5.8/spkg/build/sage-5.8/c_lib/src/stdsage.c	2013-01-25 21:54:49.832112199 -0200
+@@ -29,27 +29,12 @@ void init_global_empty_tuple(void) {
+   global_empty_tuple = PyTuple_New(0);
+ }
+ 
+-
+-/*
+-  This function gets called whenever NTL calls Error().
+-  s is the error message generated by NTL.
+-  We just copy the error message into a global buffer, and then abort() to run
+-  the usual interrupt machinery.
+- */
+-void global_NTL_error_callback(const char* s, void* context)
+-{
+-    set_sage_signal_handler_message(s);
+-    abort();
+-}
+-
+-
+ /* This is called once during Sage startup. On some platforms like
+  * Cygwin, this is also called from init_csage_module(). */
+ void init_csage() {
+     init_global_empty_tuple();
+     init_memory_functions();
+     setup_sage_signal_handler();
+-    setup_NTL_error_callback(global_NTL_error_callback, NULL);
+ }
+ 
+ /* This is called once for every single module that links in stdsage */
diff --git a/sagemath.spec b/sagemath.spec
new file mode 100644
index 0000000..6bc19c0
--- /dev/null
+++ b/sagemath.spec
@@ -0,0 +1,1554 @@
+# of a system package
+%global __provides_exclude_from	.*/site-packages/.*\\.so
+
+# for quicker test with packages not yet in fedora
+%global packager_debug		0
+
+# for quicker fedora-review tests without downloading the main tarball
+%global download_tarball	0
+
+# not functional due to missing jar dependencies
+%global with_sage3d		0
+
+# use an workaround to match upstream sagemath patched sphinx
+%global with_sphinx_hack	1
+
+# sagemath works only with pexpect-2.0
+%global with_sage_pexpect	1
+
+# https://bugzilla.redhat.com/show_bug.cgi?id=909510
+%global have_lrcalc		%{packager_debug}
+
+# Cbc dependency under review is as follow:
+#  first need coin-or-CoinUtils
+# 	https://bugzilla.redhat.com/show_bug.cgi?id=894585
+#  then coin-or-Osi (that requires coin-or-CoinUtils)
+#	https://bugzilla.redhat.com/show_bug.cgi?id=894586
+#  then coin-or-Clp (that requires coin-or-Osi)
+#	https://bugzilla.redhat.com/show_bug.cgi?id=894587
+# then coin-or-Cgl (that requires coin-or-Clp)
+#	https://bugzilla.redhat.com/show_bug.cgi?id=894588
+# and finally coin-or-Cbc (that requires coin-or-Cgl)
+#	https://bugzilla.redhat.com/show_bug.cgi?id=894597
+# other coin-or-* packages under review are not required by sagemath
+# but are required to have the "basic" set of coin-or packages
+%global have_coin_or_Cbc	%{packager_debug}
+
+# https://bugzilla.redhat.com/show_bug.cgi?id=919703
+# https://bitbucket.org/vbraun/libgap/issue/1/please-make-tarball-downloads-available
+%global have_libgap		0
+
+# https://bugzilla.redhat.com/show_bug.cgi?id=914936
+%ifarch %{ix86} x86_64
+%global have_fes		%{packager_debug}
+%else
+%global have_fes		0
+%endif
+
+# set to run sage -testall in %%install
+%global with_check		0
+%global SAGE_TIMEOUT		60
+%global SAGE_TIMEOUT_LONG	180
+
+%global conway_polynomials_pkg	conway_polynomials-0.4.p0
+%global	elliptic_curves_pkg	elliptic_curves-0.7
+%global	flintqs_pkg		flintqs-20070817.p8
+%global graphs_pkg		graphs-20120404.p4
+%global pexpect_pkg		pexpect-2.0.p5
+%global polytopes_db_pkg	polytopes_db-20100210.p2
+%global rubiks_pkg		rubiks-20070912.p18
+%global	sagenb_pkg		sagenb-0.10.4
+%global sagetex_pkg		sagetex-2.3.3.p2
+
+%global sagemath_share		%{_datadir}/%{name}
+
+%global SAGE_ROOT		%{_libdir}/sagemath
+%global SAGE_LOCAL		%{SAGE_ROOT}/local
+%global SAGE_DEVEL		%{SAGE_ROOT}/devel
+%global SAGE_DOC		%{_docdir}/%{name}-%{version}
+%global SAGE_SHARE		%{_datadir}/sagemath
+%global SAGE_EXTCODE		%{SAGE_SHARE}/extcode
+%global SAGE_PYTHONPATH		%{SAGE_ROOT}/site-packages
+
+Name:		sagemath
+Group:		Applications/Engineering
+Summary:	A free open-source mathematics software system
+Version:	5.8
+Release:	4%{?dist}
+# The file ${SAGE_ROOT}/COPYING.txt is the upstream license breakdown file
+# Additionally, every $files section has a comment with the license name
+# before files with that license
+License:	ASL 2.0 and BSD and GPL+ and GPLv2+ and LGPLv2+ and MIT and Public Domain
+URL:		http://www.sagemath.org
+%if %{download_tarball}
+Source0:	http://boxen.math.washington.edu/home/%{name}/sage-mirror/src/sage-%{version}.tar
+%else
+Source0:	sage-%{version}.tar
+%endif
+Source1:	gprc.expect
+Source2:	makecmds.sty
+# not installed by jmol package, use one in sagemath jmol spkg
+Source3:	Jmol.js
+Source4:	JmolHelp.html
+# from jmol-12.3.27.p2 spkg
+Source5:	testjava.sh
+
+# 1. scons ignores most environment variables
+# 2. scons 2.2* does not have soname support (expected for scons 2.3*)
+# This patch adds some regex substition templates for CFLAGS, etc, and
+# minor adaptation from full scons patch at:
+# http://scons.tigris.org/nonav/issues/showattachment.cgi/902/soname_func.py
+# Discussed at:
+# http://scons.tigris.org/issues/show_bug.cgi?id=2869
+Patch0:		%{name}-scons.patch
+
+# Upstream uses mpir not gmp, but the rpm package is tailored to use gmp
+Patch1:		%{name}-gmp.patch
+
+# Set of patches to work with system wide packages
+Patch2:		%{name}-scripts.patch
+
+# Do not mandate a patched ntl. It was requested to ntl upstream to
+# provide an api to match what sagemath expects.
+# http://shoup.net/pipermail/ntl_shoup.net/2012-April/000033.html
+Patch3:		%{name}-unpatched_ntl.patch
+
+# remove call to not implemented sagemath "is_package_installed" interfaces
+# need to package coin-or solver in fedora
+# remove check for non free solvers
+Patch4:		%{name}-extensions.patch
+
+# helper to:
+#	o respect a DESTDIR environment variable
+#	o avoid double '//' in pathnames, what can confused debugedit & co
+#	o minor change to help in incremental builds by avoiding rebuilding
+#	  files
+#	o do not assume there is an installed sagemath
+Patch5:		%{name}-rpmbuild.patch
+
+# avoid buildroot in some binaries due to not expanding symlinks
+Patch6:		%{name}-buildroot.patch
+
+# build documentation in buildroot environment
+Patch7:		%{name}-sagedoc.patch
+
+# sage notebook rpm and system environment adjustments
+Patch8:		%{name}-sagenb.patch
+
+# do not attempt to create state files in system directories
+Patch9:		%{name}-readonly.patch
+
+# force coercion of ecl t_string to ecl t_base_string
+# this is hackish and only required if ecl is built with unicode support
+Patch10:	%{name}-ecl-unicode.patch
+
+# do not link explicitly to png12
+Patch11:	%{name}-png.patch
+
+# work with all maxima-runtime lisp backend packages
+Patch12:	%{name}-maxima.patch
+
+# execute 4ti2 programs in $PATH not in $SAGE_ROOT/local/bin
+Patch13:	%{name}-4ti2.patch
+
+# http://trac.sagemath.org/sage_trac/ticket/12992
+# http://pari.math.u-bordeaux.fr/cgi-bin/bugreport.cgi?bug=1317
+Patch14:	%{name}-pari.patch
+
+# in fedora 18 it was updated to latest fplll
+Patch15:	%{name}-fplll.patch
+
+# Portuguese translations: http://trac.sagemath.org/sage_trac/ticket/12822
+Patch16:	trac_12502_pt_translation_of_a_tour_of_sage_rebase1.patch
+Patch17:	trac_12822_pt_translation_of_tutorial.patch
+Patch18:	trac_12822_pt_translation_of_tutorial_rev1.patch
+
+# wrappers for distros with libmpc 0.9
+Patch19:	%{name}-libmpc.patch
+
+# use jmol itself to export preview images
+# FIXME besides not using X and told so, fails if DISPLAY is not set
+Patch20:	%{name}-jmol.patch
+
+# adapt for maxima 5.29.1 package
+Patch21:	%{name}-maxima.system.patch
+
+# only cremona mini database built and installed
+# FIXME add a package with the full cremona database
+# FIXME actually it should be already available in pari-elldata
+Patch22:	%{name}-cremona.patch
+
+# lrslib is a requires
+Patch23:	%{name}-lrslib.patch
+
+# nauty cannot be packaged due to license restrictions
+# http://cs.anu.edu.au/~bdm/nauty/
+# http://pallini.di.uniroma1.it/
+Patch24:	%{name}-nauty.patch
+
+# gap hap package not (yet) available
+# http://www-gap.mcs.st-and.ac.uk/Packages/hap.html
+Patch25:	%{name}-gap-hap.patch
+
+# Patch to enable lrcalc once review request is done in Fedora
+Patch26:	%{name}-lrcalc.patch
+
+# Patch to enable cbc once review requests are done in Fedora
+Patch27:	%{name}-cbc.patch
+
+# Patch to enable libgap once review request is done in Fedora
+Patch28:	%{name}-libgap.patch
+
+# Patch to disable libgap because it is not optional by default
+Patch29:	%{name}-nolibgap.patch
+
+# Patch to enable fes once review requests are done in Fedora
+Patch30:	%{name}-fes.patch
+
+# Get package to build with known problem if not yet updated to pari 2.6.
+Patch31:	%{name}-nopari2.6.patch
+
+# sagemath 5.8 (optionally) requires cryptominisat 2.9.6 (in rawhide)
+# and does not work with cryptominisat 2.9.5 (in f18)
+Patch32:	%{name}-cryptominisat.patch
+
+BuildRequires:	4ti2
+BuildRequires:	atlas-devel
+BuildRequires:	cddlib-tools
+BuildRequires:	cliquer-devel
+%if %{have_coin_or_Cbc}
+BuildRequires:	coin-or-Cbc-devel
+%endif
+BuildRequires:	cryptominisat-devel
+BuildRequires:	Cython
+BuildRequires:	desktop-file-utils
+BuildRequires:	dos2unix
+BuildRequires:	dvipng
+BuildRequires:	ecl
+BuildRequires:	eclib-devel
+BuildRequires:	factory-devel
+%if %{have_fes}
+BuildRequires:	fes-devel
+%endif
+BuildRequires:	flint-devel
+BuildRequires:	gmp-ecm-devel
+BuildRequires:	gap
+BuildRequires:	GAPDoc
+BuildRequires:	gap-character-tables
+BuildRequires:	gap-prim-groups
+BuildRequires:	gap-small-groups
+BuildRequires:	gap-sonata
+BuildRequires:	gap-table-of-marks
+BuildRequires:	gap-trans-groups
+BuildRequires:	gc-devel
+BuildRequires:	gd-devel
+BuildRequires:	gfan
+BuildRequires:	glpk-devel
+BuildRequires:	gnutls-devel
+BuildRequires:	gsl-devel
+BuildRequires:	iml-devel
+BuildRequires:	L-function-devel
+BuildRequires:	libfac-devel
+BuildRequires:	libfplll-devel
+%if %{have_libgap}
+BuildRequires:	libgap-devel
+%endif
+BuildRequires:	libmpc-devel
+BuildRequires:	linbox-devel
+%if %{have_lrcalc}
+BuildRequires:	lrcalc-devel
+%endif
+BuildRequires:	m4ri-devel
+BuildRequires:	m4rie-devel
+BuildRequires:	maxima-runtime-ecl
+BuildRequires:	mpfi-devel
+BuildRequires:	ntl-devel
+BuildRequires:	numpy
+BuildRequires:	palp
+BuildRequires:	pari-devel
+BuildRequires:	pari-gp
+BuildRequires:	ppl-devel
+BuildRequires:	pynac-devel
+BuildRequires:	python2-devel
+BuildRequires:	python-flask-autoindex
+BuildRequires:	python-flask-babel
+BuildRequires:	python-flask-openid
+BuildRequires:	python-flask-silk
+BuildRequires:	python-ipython
+BuildRequires:	python-matplotlib
+BuildRequires:	python-networkx
+BuildRequires:	python-twisted-web
+BuildRequires:	python-twisted-web2
+BuildRequires:	polybori-devel
+BuildRequires:	R
+BuildRequires:	ratpoints-devel
+BuildRequires:	readline-devel
+BuildRequires:	rpy
+BuildRequires:	scons
+BuildRequires:	Singular-devel
+%if 0%{?fedora} >= 18
+BuildRequires:	stix-math-fonts
+%else
+BuildRequires:	stix-fonts
+%endif
+BuildRequires:	sympow
+BuildRequires:	sympy
+BuildRequires:	symmetrica-devel
+BuildRequires:	texlive
+
+Requires:	4ti2
+Requires:	apache-commons-cli
+Requires:	cddlib-tools
+Requires:	Cython
+Requires:	ecl
+Requires:	firefox
+Requires:	gap
+Requires:	GAPDoc
+Requires:	gap-character-tables
+Requires:	gap-prim-groups
+Requires:	gap-small-groups
+Requires:	gap-sonata
+Requires:	gap-table-of-marks
+Requires:	gap-trans-groups
+Requires:	genus2reduction
+Requires:	gfan
+Requires:	gmp-ecm
+Requires:	jmol
+Requires:	jsmath-fonts
+Requires:	lrslib-utils
+Requires:	maxima-gui
+Requires:	maxima-runtime-ecl
+Requires:	palp
+Requires:	pari-gp
+Requires:	python-crypto
+Requires:	python-cvxopt
+Requires:	python-flask-autoindex
+Requires:	python-flask-babel
+Requires:	python-flask-openid
+Requires:	python-flask-silk
+Requires:	python-ipython
+Requires:	python-matplotlib
+Requires:	python-networkx
+Requires:	python-polybori
+Requires:	python-twisted-web
+Requires:	python-twisted-web2
+Requires:	python-ZODB3
+Requires:	R
+Requires:	rpy
+Requires:	%{name}-core
+Requires:	%{name}-data
+Requires:	%{name}-doc-en
+Requires:	%{name}-notebook
+Requires:	%{name}-rubiks
+Requires:	%{name}-sagetex
+Requires:	Singular
+%if 0%{?fedora} >= 18
+Requires:	stix-math-fonts
+%else
+Requires:	stix-fonts
+%endif
+Requires:	sympow
+Requires:	sympy
+Requires:	tachyon
+Requires:	texlive
+Requires:	vecmath
+
+%description
+Sage is a free open-source mathematics software system licensed
+under the GPL. It combines the power of many existing open-source
+packages into a common Python-based interface.
+
+#------------------------------------------------------------------------
+%package	core
+Summary:	Open Source Mathematics Software
+Group:		Applications/Engineering
+Requires:	%{name}%{?_isa} = %{version}-%{release}
+
+%description	core
+This package contains the core sagemath python modules.
+
+#------------------------------------------------------------------------
+%package	data
+Summary:	Databases and scripts for %{name}
+Group:		Applications/Engineering
+Requires:	%{name} = %{version}-%{release}
+Requires:	%{name}-data-conway_polynomials = %{version}-%{release}
+Requires:	%{name}-data-elliptic_curves = %{version}-%{release}
+Requires:	%{name}-data-extcode = %{version}-%{release}
+Requires:	%{name}-data-graphs = %{version}-%{release}
+Requires:	%{name}-data-polytopes_db = %{version}-%{release}
+BuildArch:	noarch
+
+%description	data
+Collection of databases and interface customization scripts for sagemath.
+
+#------------------------------------------------------------------------
+%package	data-conway_polynomials
+Summary:	Conway Polynomials Database
+Group:		Applications/Engineering
+Requires:	%{name}-data = %{version}-%{release}
+BuildArch:	noarch
+
+%description	data-conway_polynomials
+Small database of Conway polynomials for sagemath.
+
+#------------------------------------------------------------------------
+%package	data-elliptic_curves
+Summary:	Databases of elliptic curves
+Group:		Applications/Engineering
+Requires:	%{name}-data = %{version}-%{release}
+BuildArch:	noarch
+
+%description	data-elliptic_curves
+Includes two databases:
+
+ * A small subset of the data in John Cremona's database of elliptic curves up
+   to conductor 10000. See http://www.warwick.ac.uk/~masgaj/ftp/data/ or
+   http://sage.math.washington.edu/cremona/INDEX.html
+
+ * William Stein's database of interesting curves
+
+#------------------------------------------------------------------------
+%package	data-extcode
+Summary:	Extcode for Sagemath
+Group:		Applications/Engineering
+Requires:	%{name}-data = %{version}-%{release}
+BuildArch:	noarch
+
+%description	data-extcode
+Collection of scripts and interfaces to sagemath.
+
+#------------------------------------------------------------------------
+%package	data-graphs
+Summary:	Sagemath database of graphs
+Group:		Applications/Engineering
+Requires:	%{name}-data = %{version}-%{release}
+BuildArch:	noarch
+
+%description	data-graphs
+A database of graphs. Created by Emily Kirkman based on the work of Jason
+Grout. Since April 2012 it also contains the ISGCI graph database.
+
+#------------------------------------------------------------------------
+%package	data-polytopes_db
+Summary:	Lists of 2- and 3-dimensional reflexive polytopes
+Group:		Applications/Engineering
+Requires:	%{name}-data = %{version}-%{release}
+BuildArch:	noarch
+
+%description	data-polytopes_db
+The list of polygons is quite easy to get and it has been known for a while.
+The list of 3-polytopes was originally obtained by Maximilian Kreuzer and
+Harald Skarke using their software PALP, which is included into the standard
+distribution of Sage. To work with lattice and reflexive polytopes from Sage
+you can use sage.geometry.lattice_polytope module, which relies on PALP for
+some of its functionality. To get access to the databases of this package, use
+ReflexivePolytope and ReflexivePolytopes commands.
+
+#------------------------------------------------------------------------
+%package	devel
+Summary:	Development files for %{name}
+Group:		Development/Libraries
+Requires:	%{name}%{?_isa} = %{version}-%{release}
+
+%description	devel
+This package contains the header files and development documentation
+for %{name}.
+
+#------------------------------------------------------------------------
+%package	doc
+Summary:	Documentation infrastructure files for %{name}
+Group:		Documentation
+BuildArch:	noarch
+
+%description	doc
+This package contains the documentation infrastructure for %{name}.
+
+#------------------------------------------------------------------------
+%package	doc-de
+Summary:	German documentation files for %{name}
+Group:		Documentation
+Requires:	%{name}-doc = %{version}-%{release}
+BuildArch:	noarch
+
+%description	doc-de
+This package contains the German %{name} documentation.
+
+#------------------------------------------------------------------------
+%package	doc-en
+Summary:	English documentation files for %{name}
+Group:		Documentation
+Requires:	%{name}-doc = %{version}-%{release}
+BuildArch:	noarch
+
+%description	doc-en
+This package contains the English %{name} documentation.
+
+#------------------------------------------------------------------------
+%package	doc-fr
+Summary:	French documentation files for %{name}
+Group:		Documentation
+Requires:	%{name}-doc = %{version}-%{release}
+BuildArch:	noarch
+
+%description	doc-fr
+This package contains the French %{name} documentation.
+
+#------------------------------------------------------------------------
+%package	doc-pt
+Summary:	Portuguese documentation files for %{name}
+Group:		Documentation
+Requires:	%{name}-doc = %{version}-%{release}
+BuildArch:	noarch
+
+%description	doc-pt
+This package contains the Portuguese %{name} documentation.
+
+#------------------------------------------------------------------------
+%package	doc-ru
+Summary:	Russian documentation files for %{name}
+Group:		Documentation
+Requires:	%{name}-doc = %{version}-%{release}
+BuildArch:	noarch
+
+%description	doc-ru
+This package contains the Russian %{name} documentation.
+
+#------------------------------------------------------------------------
+%package	doc-tr
+Summary:	Turkish documentation files for %{name}
+Group:		Documentation
+Requires:	%{name}-doc = %{version}-%{release}
+BuildArch:	noarch
+
+%description	doc-tr
+This package contains the Turkish %{name} documentation.
+
+#------------------------------------------------------------------------
+%package	notebook
+Summary:	The Sage Notebook
+Group:		Applications/Engineering
+Requires:	%{name}%{?_isa} = %{version}-%{release}
+
+%description	notebook
+The Sage Notebook is a web-based graphical user interface for
+mathematical software.
+
+#------------------------------------------------------------------------
+%package	rubiks
+Summary:	Several programs for working with Rubik's cubes
+Group:		Applications/Engineering
+Requires:	%{name}%{?_isa} = %{version}-%{release}
+
+%description	rubiks
+Several programs for working with Rubik's cubes, by three  different people.
+In summary the three contributors are:
+
+Michael Reid (GPL) http://www.math.ucf.edu/~reid/Rubik/optimal_solver.html
+    optimal - uses many pre-computed tables to find an optimal 
+              solution to the 3x3x3 Rubik's cube
+
+Dik T. Winter (MIT License)
+    cube    - uses Kociemba's algorithm to iteratively find a short
+              solution to the 3x3x3 Rubik's cube 
+    size222 - solves a 2x2x2 Rubik's cube 
+
+Eric Dietz (GPL) http://www.wrongway.org/?rubiksource
+    cu2   - A fast, non-optimal 2x2x2 solver
+    cubex - A fast, non-optimal 3x3x3 solver
+    mcube - A fast, non-optimal 4x4x4 solver
+
+#------------------------------------------------------------------------
+%package	sagetex
+Summary:	Sagemath into LaTeX documents
+Group:		Applications/Engineering
+Requires:	%{name}%{?_isa} = %{version}-%{release}
+
+%description	sagetex
+This is the SageTeX package. It allows you to embed code, results of
+computations, and plots from the Sage mathematics software suite
+(http://sagemath.org) into LaTeX documents.
+
+########################################################################
+%prep
+%setup -q -n sage-%{version}
+
+mkdir -p spkg/build
+pushd spkg/build
+    for pkg in					\
+	%{conway_polynomials_pkg}		\
+	%{elliptic_curves_pkg}			\
+	extcode-%{version}			\
+	%{flintqs_pkg}				\
+	%{graphs_pkg}				\
+%if %{with_sage_pexpect}
+	%{pexpect_pkg}				\
+%endif
+	%{polytopes_db_pkg}			\
+	%{rubiks_pkg}				\
+	%{sagenb_pkg}				\
+	%{sagetex_pkg}				\
+	sage-%{version}				\
+	sage_scripts-%{version}			\
+    ; do
+	tar jxf ../standard/$pkg.spkg
+    done
+
+    # apply in spkgs that do not have patches already applied
+    # or that actually have patches
+pushd %{flintqs_pkg}/src
+    for diff in `ls ../patches/*.patch`; do
+	patch -p1 < $diff
+    done
+popd
+
+pushd %{sagenb_pkg}/src
+    tar zxf %{sagenb_pkg}.tar.gz
+    mv  %{sagenb_pkg} sagenb
+popd
+
+%if %{with_sage_pexpect}
+    pushd %{pexpect_pkg}/src
+	for diff in `ls ../patches/*.patch ../patches/*.diff`; do
+	    patch -p1 < $diff
+	done
+    popd
+%endif
+    pushd %{rubiks_pkg}
+	cp patches/dietz-mcube-Makefile src/dietz/mcube/Makefile
+	cp patches/dietz-solver-Makefile src/dietz/solver/Makefile
+	cp patches/dietz-cu2-Makefile src/dietz/cu2/Makefile
+	cp patches/reid-Makefile src/reid/Makefile
+    popd
+popd
+
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+
+%if 0%{?fedora} >= 18
+%patch15 -p1
+%endif
+
+pushd spkg/build/sage-%{version}
+mkdir -p doc/pt/a_tour_of_sage/
+cp -fa doc/en/a_tour_of_sage/*.png doc/pt/a_tour_of_sage/
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+popd
+
+%if 0%{?fedora} <= 19
+%patch19 -p1
+%endif
+
+%patch20 -p1
+
+%if 0%{?fedora} >= 18
+%patch21 -p1
+%endif
+
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+
+%if %{have_lrcalc}
+%patch26 -p1
+%endif
+
+# other coin-or packages are build requires or coin-or-Cbc
+%if %{have_coin_or_Cbc}
+%patch27 -p1
+%endif
+
+%if %{have_libgap}
+%patch28 -p1
+%else
+%patch29 -p1
+%endif
+
+%if %{have_fes}
+%patch30 -p1
+%endif
+
+%patch31 -p1
+
+%if 0%{?fedora} >= 19
+%patch32 -p1
+%endif
+
+#------------------------------------------------------------------------
+# ensure proper/preferred libatlas is in linker path
+pushd spkg/build/sage-%{version}
+    perl -pi -e 's|^(extra_link_args = ).*|$1\["-L%{_libdir}/atlas"\]|;' sage/misc/cython.py
+    # some .c files are not (re)generated
+    find . \( -name \*.pyx -o -name \*.pxd \) | xargs touch
+popd
+
+# remove bundled jar files before build
+rm spkg/build/extcode-%{version}/notebook/java/3d/lib/sage3d.jar \
+   spkg/build/%{sagenb_pkg}/src/sagenb/sagenb/data/sage3d/lib/sage3d.jar
+
+# remove binary egg
+rm -r spkg/build/%{sagenb_pkg}/src/sagenb/sagenb.egg-info
+
+########################################################################
+%build
+export CFLAGS="%{optflags}"
+export CXXFLAGS="%{optflags}"
+export SAGE_ROOT=%{buildroot}%{SAGE_ROOT}
+export SAGE_LOCAL=%{buildroot}%{SAGE_LOCAL}
+export SAGE_DEVEL=%{buildroot}%{SAGE_DEVEL}
+export SAGE_FORTRAN=%{_bindir}/gfortran
+export SAGE_FORTRAN_LIB=`gfortran --print-file-name=libgfortran.so`
+export DESTDIR=%{buildroot}
+# Use file in /tmp because there are issues with long pathnames
+export DOT_SAGE=/tmp/sage$$
+mkdir -p $DOT_SAGE/tmp
+
+# match system packages as sagemath packages
+export SAGE_ROOT=%{buildroot}%{SAGE_ROOT}
+export SAGE_LOCAL=%{buildroot}%{SAGE_LOCAL}
+export SAGE_DEVEL=%{buildroot}%{SAGE_DEVEL}
+mkdir -p $SAGE_ROOT $SAGE_LOCAL $SAGE_DEVEL/sage
+ln -sf $PWD/spkg/build/sage-%{version}/sage $SAGE_DEVEL/sage/sage
+ln -sf %{_libdir} $SAGE_LOCAL/lib
+ln -sf %{_includedir} $SAGE_LOCAL/include
+ln -sf %{_datadir} $SAGE_LOCAL/share
+
+export PATH=%{buildroot}%{_bindir}:$PATH
+export PYTHONPATH=%{buildroot}%{python_sitearch}:$PYTHONPATH
+
+#------------------------------------------------------------------------
+pushd spkg/build/sage-%{version}
+    pushd c_lib
+	# scons ignores most environment variables
+	# and does not have soname support
+	sed -e 's|@@includedir@@|%{_includedir}|g' \
+	    -e 's|@@libdir@@|%{_libdir}|g' \
+	    -e 's|@@optflags@@|%{optflags}|g' \
+	    -e 's|@@__global_ldflags@@|%{__global_ldflags}|g' \
+	    -i SConstruct
+	CXX=g++ UNAME=Linux SAGE64=auto scons
+	ln -s libcsage.so.0 libcsage.so
+    popd
+    pushd sage/libs/mpmath
+	dos2unix ext_impl.pxd ext_libmp.pyx ext_main.pxd ext_main.pyx
+    popd
+    python ./setup.py build
+popd
+
+#------------------------------------------------------------------------
+pushd spkg/build/%{sagenb_pkg}/src/sagenb
+    python ./setup.py build
+popd
+
+#------------------------------------------------------------------------
+pushd spkg/build/%{flintqs_pkg}/src
+    make %{?_smpflags} CPP="g++ %{optflags} -fPIC"
+popd
+
+pushd spkg/build/%{rubiks_pkg}/src
+    make %{?_smp_mflags} CC="gcc -fPIC" CXX="g++ -fPIC" CFLAGS="%{optflags}" CXXFLAGS="%{optflags}"
+popd
+
+# last build command
+rm -fr $DOT_SAGE
+
+########################################################################
+%install
+export SAGE_ROOT=%{buildroot}%{SAGE_ROOT}
+export SAGE_LOCAL=%{buildroot}%{SAGE_LOCAL}
+export SAGE_DEVEL=%{buildroot}%{SAGE_DEVEL}
+export SAGE_SHARE=%{buildroot}%{SAGE_SHARE}
+export SAGE_EXTCODE=%{buildroot}%{SAGE_EXTCODE}
+export SAGE_DOC=%{buildroot}%{SAGE_DOC}
+export SAGE_PYTHONPATH=%{buildroot}%{SAGE_PYTHONPATH}
+export LD_LIBRARY_PATH=%{buildroot}%{_libdir}:$LD_LIBRARY_PATH
+export DESTDIR=%{buildroot}
+export DOT_SAGE=/tmp/sage$$
+mkdir -p $DOT_SAGE/tmp
+
+export PATH=%{buildroot}%{_bindir}:$PATH
+export PYTHONPATH=%{buildroot}%{python_sitearch}:$PYTHONPATH
+
+#------------------------------------------------------------------------
+mkdir -p %{buildroot}%{_bindir}
+mkdir -p %{buildroot}%{_libdir}
+mkdir -p $SAGE_PYTHONPATH
+rm -fr $SAGE_DEVEL/sage $SAGE_LOCAL/{include,lib,share,notebook}
+mkdir -p $SAGE_SHARE $SAGE_DOC $SAGE_LOCAL/bin $SAGE_DEVEL/sage
+ln -sf $PWD/spkg/build/sage-%{version}/sage $SAGE_DEVEL/sage/sage
+ln -sf %{_libdir} $SAGE_LOCAL/lib
+ln -sf %{_includedir} $SAGE_LOCAL/include
+ln -sf %{_datadir} $SAGE_LOCAL/share
+
+#------------------------------------------------------------------------
+pushd spkg/build/sage-%{version}
+    python setup.py install --root=%{buildroot}
+    cp -fa c_lib/libcsage.so.0 %{buildroot}%{_libdir}
+    ln -sf libcsage.so.0 %{buildroot}%{_libdir}/libcsage.so
+    pushd sage
+	# install sage notebook templates
+	cp -fa server/notebook/templates %{buildroot}%{python_sitearch}/sage/server/notebook
+    popd
+    # install documentation sources
+    rm -fr $SAGE_DOC/{common,en,fr}
+    cp -far doc/{common,de,en,fr,pt,ru,tr} $SAGE_DOC
+popd
+
+#------------------------------------------------------------------------
+pushd spkg/build/%{sagenb_pkg}/src/sagenb
+    rm -f %{buildroot}%{python_sitearch}/sagenb/data/sage3d/sage3d
+    python setup.py install --root=%{buildroot} --install-purelib=%{python_sitearch}
+    install -p -m0755 %{SOURCE5} $SAGE_LOCAL/bin/testjava.sh
+    # jmol
+    rm -fr %{buildroot}%{python_sitearch}/sagenb/data/jmol
+    mkdir -p %{buildroot}%{python_sitearch}/sagenb/data/jmol/appletweb
+    pushd %{buildroot}%{python_sitearch}/sagenb/data/jmol
+	cp -fa %{SOURCE3} %{SOURCE4} appletweb
+    popd
+    # sage3d
+    rm -f %{buildroot}%{_bindir}/sage3d
+%if %{with_sage3d}
+    ln -sf %{SAGE_LOCAL}/bin/sage3d %{buildroot}%{python_sitearch}/sagenb/data/sage3d/sage3d
+%endif
+    # flask stuff not installed
+    cp -ar flask_version %{buildroot}%{python_sitearch}/sagenb
+    ln -sf %{python_sitearch}/sagenb %{buildroot}%{SAGE_DEVEL}/sagenb
+popd
+
+#------------------------------------------------------------------------
+%if %{with_sage_pexpect}
+pushd spkg/build/%{pexpect_pkg}/src
+    cp -fa {ANSI,FSM,pexpect,pxssh,screen}.py $SAGE_PYTHONPATH
+popd
+%endif
+
+#------------------------------------------------------------------------
+cp -fa COPYING.txt $SAGE_ROOT
+pushd spkg/build/sage_scripts-%{version}
+    mkdir -p $SAGE_LOCAL/bin
+    cp -fa sage-* *doctest.py $SAGE_LOCAL/bin
+    pushd $SAGE_LOCAL/bin
+	ln -sf %{_bindir}/python sage.bin
+	ln -sf %{_bindir}/gp sage_pari
+	ln -sf %{_bindir}/gap gap_stamp
+	ln -sf %{_bindir}/gmp-ecm ecm
+    popd
+popd
+install -p -m755 spkg/bin/sage $SAGE_LOCAL/bin
+
+#------------------------------------------------------------------------
+pushd spkg/build/%{flintqs_pkg}/src
+    cp -fa QuadraticSieve $SAGE_LOCAL/bin
+popd
+
+pushd spkg/build/%{rubiks_pkg}/src
+    cp -fa \
+	reid/optimal \
+	dietz/solver/cubex \
+	dietz/mcube/mcube \
+	dietz/cu2/cu2 \
+	dik/dikcube \
+	dik/size222 \
+	$SAGE_LOCAL/bin
+popd
+
+#------------------------------------------------------------------------
+rm -f %{buildroot}%{_bindir}/spkg-debian-maybe
+pushd $SAGE_LOCAL/bin/
+    rm -f sage-{bdist,build,build-debian,clone,crap,debsource,download_package,env,libdist,location,make_devel_packages,omega,pkg,pkg-nocompress,pull,push,sdist,sbuildhack,upgrade}
+    rm -f sage-list-* sage-mirror* SbuildHack.pm sage-test-*
+    rm -f sage-{verify-pyc,hardcode_sage_root,check-64,spkg*,update*,starts}
+    rm -f *~
+    rm -f sage-{check-libraries.py,ldwrap,open,osx-open,README-osx.txt}
+    rm -f sage-rebase_sage.sh
+    rm -f sage-{combinat,massif}
+popd
+
+#------------------------------------------------------------------------
+pushd spkg/build/%{conway_polynomials_pkg}
+    %__python2 ./spkg-install
+popd
+
+#------------------------------------------------------------------------
+pushd spkg/build/%{elliptic_curves_pkg}
+    %__python2 ./spkg-install
+popd
+
+#------------------------------------------------------------------------
+pushd spkg/build/extcode-%{version}
+    mkdir -p $SAGE_EXTCODE
+    for dir in 			\
+	gap			\
+	genus2reduction		\
+	gnuplot			\
+	images			\
+	kash			\
+	macaulay2		\
+	magma			\
+	maple			\
+	matlab			\
+	mathematica		\
+	maxima			\
+	MuPAD			\
+	mwrank			\
+	octave			\
+	QEPCAD			\
+	scilab			\
+	singular		\
+	sobj; do
+	COUNT=`find $dir -type f | wc -l `
+	if [ $COUNT -gt 0 ]; then
+	    cp -far $dir $SAGE_EXTCODE
+	fi
+	cp -far pari $SAGE_EXTCODE
+    done
+    cp -fa %{SOURCE1} $SAGE_EXTCODE/pari
+popd
+
+#------------------------------------------------------------------------
+pushd spkg/build/%{graphs_pkg}
+    mkdir -p $SAGE_SHARE/graphs
+    cp -fa src/* $SAGE_SHARE/graphs
+popd
+
+#------------------------------------------------------------------------
+pushd spkg/build/%{polytopes_db_pkg}
+    mkdir -p $SAGE_SHARE/reflexive_polytopes
+    cp -fa src/* $SAGE_SHARE/reflexive_polytopes
+popd
+
+#------------------------------------------------------------------------
+pushd spkg/build/%{sagetex_pkg}/src
+    python setup.py install --root=%{buildroot} --install-purelib=%{python_sitearch}
+    install -p -m 0644 -D %{SOURCE2} \
+	%{buildroot}%{_datadir}/texmf/tex/generic/sagetex/makecmds.sty
+    mv %{buildroot}%{_docdir}/{sagetex,%{sagetex_pkg}}
+    mv %{buildroot}%{_datadir}/texmf/tex/generic/sagetex/CONTRIBUTORS \
+	 %{buildroot}%{_docdir}/%{sagetex_pkg}
+    for file in PKG-INFO README; do
+	install -p -m 0644 $file %{buildroot}%{_docdir}/%{sagetex_pkg}/$file
+    done
+popd
+
+#------------------------------------------------------------------------
+cat > %{buildroot}%{_bindir}/sage << EOF
+#!/bin/sh
+
+export CUR=\`pwd\`
+##export DOT_SAGE="\$HOME/.sage"
+export DOT_SAGENB="\$DOT_SAGE"
+mkdir -p \$DOT_SAGE/{maxima,sympow,tmp}
+export SAGE_TESTDIR=\$DOT_SAGE/tmp
+export SAGE_ROOT="$SAGE_ROOT"
+export SAGE_LOCAL="$SAGE_LOCAL"
+export SAGE_SHARE="$SAGE_SHARE"
+export SAGE_EXTCODE="$SAGE_EXTCODE"
+export SAGE_DEVEL="$SAGE_DEVEL"
+##export SAGE_DOC="$SAGE_DOC"
+module load 4ti2-%{_arch}
+%if %{have_lrcalc}
+module load lrcalc-%{_arch}
+%endif
+export PATH=$SAGE_LOCAL/bin:\$PATH
+export SINGULARPATH=%{_libdir}/Singular/LIB
+export SINGULAR_BIN_DIR=%{_libdir}/Singular
+##export PYTHONPATH="$SAGE_PYTHONPATH:\$SAGE_LOCAL/bin"
+export SAGE_CBLAS=cblas
+export SAGE_FORTRAN=%{_bindir}/gfortran
+export SAGE_FORTRAN_LIB=\`gfortran --print-file-name=libgfortran.so\`
+export SYMPOW_DIR="\$DOT_SAGE/sympow"
+export LC_MESSAGES=C
+export LC_NUMERIC=C
+export SAGE_BROWSER=firefox
+MALLOC_CHECK_=1 $SAGE_LOCAL/bin/sage "\$@"
+EOF
+#------------------------------------------------------------------------
+chmod +x %{buildroot}%{_bindir}/sage
+
+#------------------------------------------------------------------------
+%if %{with_sage3d}
+cat > %{buildroot}%{SAGE_LOCAL}/bin/sage3d << EOF
+#!/bin/sh
+
+java -classpath %{SAGE_DEVEL}/sage/sagenb/data/sage3d/lib/sage3d.jar:%{_javadir}/j3dcore.jar:%{_javadir}/vecmath.jar:%{_javadir}/j3dutils.jar org.sagemath.sage3d.ObjectViewerApp "\$1"
+EOF
+chmod +x %{buildroot}%{SAGE_LOCAL}/bin/sage3d
+%endif
+
+#------------------------------------------------------------------------
+# adjust cython interface:
+# o link with proper atlas
+# o install csage headers
+# o install .pxi and .pxd files
+pushd spkg/build/sage-%{version}
+    # make atlas/blas available to compiled sources
+    perl -pi -e								\
+	's|^(extra_link_args =).*|$1 ["-L%{_libdir}/atlas"]|;'		\
+	%{buildroot}%{python_sitearch}/sage/misc/cython.py
+    # make csage headers available
+    mkdir -p %{buildroot}%{_includedir}/csage
+    cp -fa c_lib/include/* %{buildroot}%{_includedir}/csage
+    for f in `find sage \( -name \*.pxi -o -name \*.pxd -o -name \*.pyx \)`; do
+	install -p -D -m 0644 $f %{buildroot}%{python_sitearch}/$f
+    done
+    # need this or will not "find" the files in the directory, and
+    # fail to link with gmp
+    touch %{buildroot}%{python_sitearch}/sage/libs/gmp/__init__.py
+popd
+
+#------------------------------------------------------------------------
+%if %{with_sage_pexpect}
+    cp -f $SAGE_PYTHONPATH/{ANSI,FSM,pexpect,pxssh,screen}.py %{buildroot}%{python_sitearch}
+%endif
+
+# Build documentation, using %#{buildroot} environment
+pushd spkg/build/sage-%{version}/doc
+    export SAGE_DOC=`pwd`
+    export PATH=%{buildroot}%{_bindir}:$SAGE_LOCAL/bin:$PATH
+    export SINGULARPATH=%{_libdir}/Singular/LIB
+    export SINGULAR_BIN_DIR=%{_libdir}/Singular
+    export LD_LIBRARY_PATH=%{buildroot}%{_libdir}:%{_libdir}/atlas:$LD_LIBRARY_PATH
+    export PYTHONPATH=%{buildroot}%{python_sitearch}:$SAGE_PYTHONPATH:$SAGE_DOC
+
+%if %{with_sphinx_hack}
+    cp -far %{python_sitelib}/sphinx %{buildroot}%{python_sitearch}
+    sed -i "s|\(source.startswith('>>>')\)|\1 or source.startswith('sage: ')|" \
+	%{buildroot}%{python_sitearch}/sphinx/highlighting.py
+%endif
+
+    # there we go
+    ln -sf %{buildroot}%{SAGE_DOC} $SAGE_ROOT/devel/doc
+    python common/builder.py all html
+    export SAGE_DOC=%{buildroot}%{SAGE_DOC}
+    cp -far output $SAGE_DOC
+
+    # should not be required and encodes buildroot
+    rm -fr $SAGE_DOC/output/doctrees
+    sed -e 's|%{buildroot}||g' -i $SAGE_DOC/output/html/en/reference/sage/misc/hg.html
+popd
+
+%if %{with_check}
+export SAGE_TIMEOUT=%{SAGE_TIMEOUT}
+export SAGE_TIMEOUT_LONG=%{SAGE_TIMEOUT_LONG}
+sage -testall --verbose || :
+install -p -m644 $DOT_SAGE/tmp/test.log $SAGE_DOC/test.log
+# remove buildroot references from test.log
+sed -i 's|%{buildroot}||g' $SAGE_DOC/test.log
+%endif
+
+%if %{with_sage_pexpect}
+    rm -f %{buildroot}%{python_sitearch}/{ANSI,FSM,pexpect,pxssh,screen}.py{,c}
+%endif
+
+%if %{with_sphinx_hack}
+    rm -fr %{buildroot}%{python_sitearch}/sphinx
+%endif
+
+# Script was used to build documentation 
+perl -pi -e 's|%{buildroot}||g;s|^##||g;' %{buildroot}%{_bindir}/sage
+
+# More wrong buildroot references
+perl -pi -e 's|%{buildroot}||g;' \
+	 -e "s|$PWD/spkg/build/sage-%{version}/doc|%{SAGE_DOC}|g;" \
+    %{buildroot}%{SAGE_DOC}/output/html/en/reference/todolist.html \
+    %{buildroot}%{SAGE_DOC}/output/html/en/reference/misc/sage/misc/hg.html
+
+#------------------------------------------------------------------------
+# Fix links
+rm -fr $SAGE_DEVEL/sage $SAGE_EXTCODE/sage $SAGE_ROOT/doc $SAGE_ROOT/devel/doc
+ln -sf %{python_sitearch} $SAGE_DEVEL/sage
+ln -sf %{python_sitearch} $SAGE_EXTCODE/sage
+ln -sf %{SAGE_DOC} $SAGE_ROOT/doc
+ln -sf %{SAGE_DOC} $SAGE_ROOT/devel/doc
+ln -sf %{SAGE_SHARE} $SAGE_ROOT/share
+rm -fr %{buildroot}%{python_sitearch}/site-packages
+
+# Install menu and icons
+pushd spkg/build/extcode-%{version}
+    install -p -m644 -D notebook/images/icon32x32.png %{buildroot}%{_datadir}/pixmaps/%{name}.png
+popd
+mkdir -p %{buildroot}%{_datadir}/applications
+cat > %{buildroot}%{_datadir}/applications/%{name}.desktop << EOF
+[Desktop Entry]
+Name=Sagemath
+Comment=A free open-source mathematics software system
+Exec=sage
+Icon=%{name}
+Terminal=true
+Type=Application
+Categories=Science;Math;
+EOF
+desktop-file-validate %{buildroot}%{_datadir}/applications/%{name}.desktop
+
+# Fix permissions
+find %{buildroot} -name '*.so' | xargs chmod 755
+pushd %{buildroot}%{SAGE_LOCAL}/bin
+    chmod 755 QuadraticSieve
+    chmod 755 mcube dikcube cu2 size222 cubex optimal
+popd
+for file in `find %{buildroot} -name \*.py`; do
+    if head -1 $file | grep -q '^#!'; then
+	chmod +x $file
+    fi
+done
+chmod -x %{buildroot}%{SAGE_DOC}/en/prep/media/Rplot001.png
+
+# Documentation is not rebuilt (also corrects rpmlint warning of hidden file)
+find %{buildroot}%{SAGE_DOC} -name .buildinfo -exec rm {} \;
+rm -fr %{buildroot}%{SAGE_DOC}/output/inventory
+find %{buildroot}%{SAGE_DOC} -type d -name _sources | xargs rm -fr
+
+rm %{buildroot}%{python_sitearch}/sagenb/data/mathjax/.gitignore \
+   %{buildroot}%{python_sitearch}/sagenb/data/mathjax/docs/.gitignore
+
+# remove bundles fonts
+rm -r %{buildroot}%{python_sitearch}/sagenb/data/mathjax/fonts
+
+# remove .po files
+rm %{buildroot}%{python_sitearch}/sagenb/translations/*/LC_MESSAGES/*.po
+
+# remove zero length files
+rm %{buildroot}%{python_sitearch}/sage/server/notebook/compress/all.py* \
+   %{buildroot}%{python_sitearch}/sage/misc/test_cpickle_sage.py*
+
+%if !%{with_sage3d}
+rm -r %{buildroot}%{python_sitearch}/sagenb/data/sage3d
+%endif
+
+# last install command
+rm -fr $DOT_SAGE
+
+########################################################################
+%post core -p /sbin/ldconfig
+
+%postun core -p /sbin/ldconfig
+
+# Use symlinks and a minor patch to the notebook to not bundle jmol
+%post		notebook
+ln -sf %{_javadir}/JmolApplet.jar %{python_sitearch}/sagenb/data/jmol/
+ln -sf %{_javadir}/vecmath.jar %{python_sitearch}/sagenb/data/jmol/
+
+%postun		notebook
+if [ $1 -eq 0 ] ; then
+    rm -f %{python_sitearch}/sagenb/data/jmol/JmolApplet.jar
+    rm -f %{python_sitearch}/sagenb/data/jmol/vecmath.jar
+    rmdir %{python_sitearch}/sagenb/data/jmol &&
+	rmdir %{python_sitearch}/sagenb/data &&
+	    rmdir %{python_sitearch}/sagenb
+fi
+
+%post		sagetex -p %{_bindir}/mktexlsr
+
+%postun		sagetex -p %{_bindir}/mktexlsr
+
+########################################################################
+%files
+# GPLv2+
+%dir %{SAGE_ROOT}
+%doc %{SAGE_ROOT}/COPYING.txt
+%dir %{SAGE_LOCAL}
+%dir %{SAGE_LOCAL}/bin
+%{SAGE_LOCAL}/bin/ncadoctest.py
+%{SAGE_LOCAL}/bin/QuadraticSieve
+%{SAGE_LOCAL}/bin/ecm
+%{SAGE_LOCAL}/bin/gap_stamp
+%{SAGE_LOCAL}/bin/sage*
+%{SAGE_LOCAL}/bin/testjava.sh
+%{SAGE_LOCAL}/include
+%{SAGE_LOCAL}/lib
+%{SAGE_LOCAL}/share
+%dir %{SAGE_DEVEL}
+%dir %{SAGE_PYTHONPATH}
+%if %{with_sage_pexpect}
+# MIT
+%{SAGE_PYTHONPATH}/*.py*
+%endif
+# GPLv2+
+%{_bindir}/sage
+%{_datadir}/pixmaps/%{name}.png
+%{_datadir}/applications/%{name}.desktop
+
+#------------------------------------------------------------------------
+%files		core
+# GPLv2+
+%{_libdir}/libcsage.so.*
+%{python_sitearch}/sage
+%{python_sitearch}/sage-*.egg-info
+
+#------------------------------------------------------------------------
+%files		data
+%dir %{SAGE_SHARE}
+%{SAGE_ROOT}/share
+%{SAGE_EXTCODE}/sage
+
+#------------------------------------------------------------------------
+%files		data-conway_polynomials
+# GPLv2+
+%{SAGE_SHARE}/conway_polynomials
+
+#------------------------------------------------------------------------
+%files		data-elliptic_curves
+# GPLv2+
+%{SAGE_SHARE}/cremona
+%{SAGE_SHARE}/ellcurves
+
+#------------------------------------------------------------------------
+%files		data-extcode
+# GPLv2+
+%dir %{SAGE_EXTCODE}
+%{SAGE_EXTCODE}/gap
+%{SAGE_EXTCODE}/images
+%{SAGE_EXTCODE}/magma
+%{SAGE_EXTCODE}/maxima
+%{SAGE_EXTCODE}/mwrank
+%{SAGE_EXTCODE}/pari
+%{SAGE_EXTCODE}/singular
+
+#------------------------------------------------------------------------
+%files		data-graphs
+# GPLv2+
+%{SAGE_SHARE}/graphs
+
+#------------------------------------------------------------------------
+%files		data-polytopes_db
+# GPL+
+%{SAGE_SHARE}/reflexive_polytopes
+
+#------------------------------------------------------------------------
+%files		devel
+# GPLv2+
+%{SAGE_DEVEL}/sage
+%{_includedir}/csage
+%{_libdir}/libcsage.so
+
+#------------------------------------------------------------------------
+%files		doc
+# GPLv2+
+%{SAGE_ROOT}/doc
+%{SAGE_DEVEL}/doc
+%dir %{SAGE_DOC}
+%{SAGE_DOC}/common
+%dir %{SAGE_DOC}/output
+%dir %{SAGE_DOC}/output/html
+
+#------------------------------------------------------------------------
+%files		doc-de
+# GPLv2+
+%{SAGE_DOC}/de
+%{SAGE_DOC}/output/html/de
+
+#------------------------------------------------------------------------
+%files		doc-en
+# GPLv2+
+%{SAGE_DOC}/en
+%{SAGE_DOC}/output/html/en
+
+#------------------------------------------------------------------------
+%files		doc-fr
+# GPLv2+
+%{SAGE_DOC}/fr
+%{SAGE_DOC}/output/html/fr
+
+#------------------------------------------------------------------------
+%files		doc-pt
+# GPLv2+
+%{SAGE_DOC}/pt
+%{SAGE_DOC}/output/html/pt
+
+#------------------------------------------------------------------------
+%files		doc-ru
+# GPLv2+
+%{SAGE_DOC}/ru
+%{SAGE_DOC}/output/html/ru
+
+#------------------------------------------------------------------------
+%files		doc-tr
+# GPLv2+
+%{SAGE_DOC}/tr
+%{SAGE_DOC}/output/html/tr
+
+#------------------------------------------------------------------------
+%files		notebook
+# GPLv2+
+%{SAGE_DEVEL}/sagenb
+%dir %{python_sitearch}/sagenb
+%{python_sitearch}/sagenb/*.py*
+%{python_sitearch}/sagenb-*.egg-info
+%dir %{python_sitearch}/sagenb/data
+# BSD
+%{python_sitearch}/sagenb/data/codemirror
+# MIT
+%{python_sitearch}/sagenb/data/graph_editor
+# ASL 2.0
+%{python_sitearch}/sagenb/data/highlight
+# LGPLv2+
+%{python_sitearch}/sagenb/data/jmol
+# (MIT or GPLv2) and (MIT and BSD and GPL)
+%{python_sitearch}/sagenb/data/jquery
+# (MIT or GPLv2) and (MIT and BSD and GPL)
+%{python_sitearch}/sagenb/data/jqueryui
+# Public Domain
+%{python_sitearch}/sagenb/data/json
+# ASL 2.0
+%{python_sitearch}/sagenb/data/mathjax
+# BSD
+%{python_sitearch}/sagenb/data/openid-realselector
+# GPLv2+
+%{python_sitearch}/sagenb/data/sage
+%if %{with_sage3d}
+# GPLv2+
+%{python_sitearch}/sagenb/data/sage3d
+%endif
+# LGPLv2+
+%{python_sitearch}/sagenb/data/tiny_mce
+# LGPLv2+
+%{python_sitearch}/sagenb/data/zorn
+# GPLv2+
+%{python_sitearch}/sagenb/flask_version
+# GPLv2+
+%{python_sitearch}/sagenb/interfaces
+# GPLv2+
+%{python_sitearch}/sagenb/misc
+# GPLv2+
+%{python_sitearch}/sagenb/notebook
+# GPLv2+
+%{python_sitearch}/sagenb/simple
+# GPLv2+
+%{python_sitearch}/sagenb/storage
+# GPLv2+
+%dir %{python_sitearch}/sagenb/testing
+%{python_sitearch}/sagenb/testing/*.py*
+%{python_sitearch}/sagenb/testing/tests
+# ASL 2.0
+%{python_sitearch}/sagenb/testing/selenium
+# GPLv2+
+%dir %{python_sitearch}/sagenb/translations
+%lang(cs_CZ) %{python_sitearch}/sagenb/translations/cs_CZ
+%lang(de_AT) %{python_sitearch}/sagenb/translations/de_AT
+%lang(pt_BR) %{python_sitearch}/sagenb/translations/pt_BR
+%lang(ru_RU) %{python_sitearch}/sagenb/translations/ru_RU
+
+#------------------------------------------------------------------------
+%files		rubiks
+# GPL+
+%{SAGE_LOCAL}/bin/optimal
+# MIT
+%{SAGE_LOCAL}/bin/dikcube
+%{SAGE_LOCAL}/bin/size222
+# GPL+
+%{SAGE_LOCAL}/bin/cu2
+%{SAGE_LOCAL}/bin/cubex
+%{SAGE_LOCAL}/bin/mcube
+
+#------------------------------------------------------------------------
+%files		sagetex
+# GPLv2+
+%{python_sitearch}/sagetex*
+%{_datadir}/texmf/tex/generic/sagetex
+%doc %{_docdir}/%{sagetex_pkg}
+
+########################################################################
+%changelog
+* Mon Apr 22 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.8-4
+- Remove noop icon cache regeneration scriplets (#877651#72)
+- First Fedora 18 and Fedora 19 approved package
+
+* Sun Apr 14 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.8-3
+- Use proper license tag for non versioned GPL attribution (#877651#63)
+- Remove no longer required workarounds for clean upgrades (#877651#63)
+
+* Fri Apr 12 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.8-2
+- Properly describe the license breakdown in the spec (#877651#60)
+- Correct lrslib requires to lrslib-utils (#877651#60)
+- Remove zero length files (#877651#60)
+- Correct png file with executable permission (#877651#60)
+- Avoid rpmlint warning in rubiks subpackage description (#877651#60)
+
+* Tue Mar 19 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.8-1
+- Update to sagemath 5.8.
+- Do full cleanup of notebook package on uninstall.
+- Remove with_sage_cython build conditional.
+- Remove with_sage_networkx build conditional.
+- Add nopari2.6 patch to not rely on not yet available interfaces.
+- Add cryptominisat patch to build package in f18.
+
+* Sat Mar 16 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.7-3
+- Create jmol symbolic links in post and remove in postun.
+- Disable libgap by default as it does not work with rawhide gap.
+- Also add python-ipython to build requires to regenerate documentation.
+
+* Wed Mar  6 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.7-2
+- Add missing python-ipython requires (#877651#52)
+- Enable libgap build in packager debug build (#877651#52)
+
+* Fri Feb 22 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.7-1
+- Update to sagemath 5.7.
+- Add conditional patch for libgap.
+- Add conditional patch for fes.
+- Remove with_sage_ipython conditional.
+- Add patch to create a libcsage with a soname.
+
+* Mon Feb 18 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.6-6
+- Rebuild with latest rawhide and f18 updates
+- Make sagemath-notebook owner of its base data directory
+- Explicitly mark notebook translations as %%lang (#877651#c46)
+- Remove sage3d as it is not functional in the rpm package (#877651#c46)
+- Remove reference to buildroot in libcsage.so debuginfo
+
+* Fri Feb 15 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.6-5
+- Export CFLAGS and CXXFLAGS (#877651#c45)
+- Make sagemath-data owner of SAGE_SHARE (#877651#c45)
+- Relocate SAGE_DOC and make sagemath-doc packages noarch (#877651#c45)
+- Relocate SAGE_SHARE and make sagemath-data packages noarch (#877651#c45)
+- Remove sagenb binary egg bundled in tarball (#877651#c45)
+- Update license tag due to unlisted Apache v2 license (#877651#c45)
+- Break down licenses in files listing (#877651#c45)
+- Add post scriplets to handle the installed icon (#877651#c45)
+- Do not install empty directories in SAGE_EXTCODE (#877651#c45)
+- Do not install bundled mathjax fonts (#877651#c45)
+- Add a descriptive comment to patches without one (#877651#c45)
+- Correct mispelled donwload_tarball macro name (#877651#c45)
+- Remove reference to buildroot in prep (#877651#c45)
+- Simplify coin-or-Cbc build requires as it has proper dependencies
+
+* Sun Feb 10 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.6-4
+- Correct "canonicalization unexpectedly shrank by one character" error.
+- Add packager_debug macro for conditional package debug mode build.
+- Add donwload_tarball macro to avoid fedora-review donwloading it every run.
+
+* Sat Feb  9 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.6-3
+- Add cryptominisat-devel to build requires.
+- Add conditional build for lrcalc (fedora review rhbz #909510)
+- Add conditional build for coin-or-CoinUtils (fedora review rhbz #894585)
+- Add conditional build for coin-or-Osi (fedora review rhbz #894586)
+- Add conditional build for coin-or-Clp (fedora review rhbz #894587)
+- Add conditional build for coin-or-Cgl (fedora review rhbz #894588)
+- Add conditional build for coin-or-Cbc (fedora review rhbz #894597)
+- Rebuild with latest rawhide and f18 dependency updates.
+
+* Mon Jan 28 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.6-2
+- Rebuild with latest rawhide and f18 updates.
+
+* Fri Jan 25 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.6-1
+- Update to sagemath 5.6.
+- Remove no longer required patch to build with system cython.
+
+* Sat Jan 19 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.5-3
+- Rediff rpmbuild patch to address some underlinked modules.
+- Make gap-sonata a mandatory requires.
+- Add cremona patch to adjust logic as only cremona mini is built.
+- Add lrslib patch to know lrslib is available.
+- Add nauty patch and comment about reason it cannot be made available.
+- Add gap-hap patch for better description of missing gap hap package.
+
+* Fri Jan 04 2013 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.5-2
+- Add cython to build requires (#877651#c28).
+
+* Sat Dec 29 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.5-1
+- Update to sagemath 5.5.
+- Add maxima.system patch to work with maxima 5.29.1 package.
+
+* Fri Dec 14 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4.1-5
+- Build with system cython by default on fedora 18 or newer (#877651).
+
+* Fri Dec 14 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4.1-4
+- The fplll patch is also required to build in f18.
+- Add factory include to plural.pyx build.
+
+* Wed Dec 05 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4.1-3
+- Revert requires python-matplotlib-tk as it was a python-matplotlib bug.
+- Add stix-fonts requires.
+
+* Sat Dec 01 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4.1-2
+- Change back to install .c and .h files in bundled cython.
+- Make symlink of gmp-ecm to $SAGE_LOCAL/bin/ecm.
+- Add SAGE_LOCAL/bin to python path so that "sage -gdb" works.
+- Require python-matplotlib-tk to avoid possible import error in doctests.
+
+* Fri Nov 30 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4.1-1
+- Update to sagemath 5.4.1.
+
+* Tue Nov 20 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4-2
+- Do not install alternate cygdb in %%_bindir
+- Create the sagemath-core subpackage
+- Create the sagemath-doc subpackage
+- Create the sagemath-doc-en subpackage
+- Create the sagemath-doc-de subpackage
+- Create the sagemath-doc-fr subpackage
+- Create the sagemath-doc-pt subpackage
+- Create the sagemath-doc-ru subpackage
+- Create the sagemath-doc-tr subpackage
+- Create the sagemath-data metapackage
+- Create the sagemath-data-conway_polynomials subpackage
+- Create the sagemath-data-elliptic_curves subpackage
+- Create the sagemath-data-extcode subpackage
+- Do not install pickle_jar extcode contents
+- Do not install notebook extcode contents
+- Create the sagemath-data-graphs subpackage
+- Create the sagemath-data-polytopes_db subpackage
+- Create the sagemath-notebook subpackage
+- Create the sagemath-rubiks subpackage
+- Create the sagemath-sagetex subpackage
+
+* Mon Nov 12 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4-1
+- Update to sagemath 5.4.
+- Build with system networkx.
+- Install only one fallback icon.
+- Prevent rpm from providing private shared object.
+- Change base directory to %%{_libdir} to avoid rpmlint errors.
+- Correct permissions of installed shared objects.
+- Rename most patches to use %%{name} prefix as "suggested" by fedora-review.
+- Remove bundled jar files before %%build.
+- Make cube solvers build optional and disabled by default.
+- Add option to run "sage -testall" during package build.
+
+* Sat Nov 10 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4.beta1-4
+- Add patch to make jmol export image functional
+- Update pari patch to use proper path to gprc.expect
+- Force usage of firefox in notebook (known to work are firefox and chromium)
+
+* Fri Oct 26 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4.beta1-3
+- Add support for releases with libmpc 0.9.
+
+* Wed Oct 24 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4.beta1-2
+- Add Portuguese translations of Tutorial and A Tour of Sage
+
+* Sat Oct 20 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.4.beta1-1
+- Update to sagemath 5.4.beta1
+- Removed already applied upstream linbox upgrade patch
+- Removed already applied upstream givaro upgrade patch
+- Removed already applied upstream singular upgrade patch
+- Install rubiks spkg binaries
+
+* Wed Sep 12 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.3-1
+- Update to sagemath 5.3.
+- Remove version from patches name.
+- Drop m4ri patch already applied to upstream.
+
+* Fri Sep 7 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.2-2
+- Add sphinx workaround to have editable tutorial forms (#839321)
+- Make interactive 3d plots using jmol applet functional (#837166)
+- Use system genus2reduction
+- Add workaround to mp_set_memory_functions call from pari library
+
+* Sat Aug 4 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.2-1
+- Update to sagemath 5.2.
+
+* Sun Jul 1 2012 pcpa <paulo.cesar.pereira.de.andrade at gmail.com> - 5.0.1-1
+- Initial sagemath spec.
diff --git a/sources b/sources
index e69de29..ff63373 100644
--- a/sources
+++ b/sources
@@ -0,0 +1 @@
+b91d6c20798f396a9c875527c78b3587  sage-5.8.tar
diff --git a/testjava.sh b/testjava.sh
new file mode 100755
index 0000000..748640e
--- /dev/null
+++ b/testjava.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+type -atp java
+OUT=$?
+#echo $OUT
+if [ $OUT -eq 0 ]; then
+#found java now check 1.5<=version<=1.7
+#version >1.7 may be OK just not checked yet.
+  java -version 2>&1|grep version.*[1]\.[567]
+else
+  exit 1
+fi
+#OUT=$?
+#echo $OUT
diff --git a/trac_12502_pt_translation_of_a_tour_of_sage_rebase1.patch b/trac_12502_pt_translation_of_a_tour_of_sage_rebase1.patch
new file mode 100644
index 0000000..65fec93
--- /dev/null
+++ b/trac_12502_pt_translation_of_a_tour_of_sage_rebase1.patch
@@ -0,0 +1,192 @@
+# HG changeset patch
+# User Gustavo de Oliveira <goliveira5d at gmail.com>
+# Date 1331804234 -3600
+# Node ID 94a5dead34f6c05d91a1ea6746cc171a7248e905
+# Parent  05f00d34acbd7a4340a322d3752461edbae46fd0
+Trac 12502: Portuguese translation of "A Tour of Sage".
+
+diff --git a/doc/pt/a_tour_of_sage/conf.py b/doc/pt/a_tour_of_sage/conf.py
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/a_tour_of_sage/conf.py
+@@ -0,0 +1,36 @@
++# -*- coding: utf-8 -*-
++#
++# Numerical Sage documentation build configuration file, created by
++# sphinx-quickstart on Sat Dec  6 11:08:04 2008.
++#
++# This file is execfile()d with the current directory set to its containing dir.
++#
++# The contents of this file are pickled, so don't put values in the namespace
++# that aren't pickleable (module imports are okay, they're removed automatically).
++#
++# All configuration values have a default; values that are commented out
++# serve to show the default.
++
++import sys, os
++sys.path.append(os.environ['SAGE_DOC'])
++from common.conf import *
++
++# General information about the project.
++project = u'Uma Turnê pelo Sage'
++name = 'a_tour_of_sage'
++language = 'pt_BR'
++
++# The name for this set of Sphinx documents.  If None, it defaults to
++# "<project> v<release> documentation".
++html_title = project + " v" + release
++html_short_title = project + " v" + release
++
++# Output file base name for HTML help builder.
++htmlhelp_basename = name
++
++# Grouping the document tree into LaTeX files. List of tuples  
++# (source start file, target name, title, author, document class [howto/manual]).
++latex_documents = [
++  ('index', name+'.tex', u'A Tour Of Sage',
++   u'The Sage Development Team', 'manual'),
++]
+diff --git a/doc/pt/a_tour_of_sage/index.rst b/doc/pt/a_tour_of_sage/index.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/a_tour_of_sage/index.rst
+@@ -0,0 +1,139 @@
++===================
++Uma Turnê pelo Sage
++===================
++
++Esta apresentação ao Sage segue de perto o "tour do Mathematica" que
++se encontra no começo do "manual do Mathematica".
++
++
++Sage como uma Calculadora
++=========================
++
++A linha de comando do Sage possui o prompt ``sage:``; você não precisa
++digitar essa palavra. Se você usar o Sage Notebook, então você deve
++copiar todo o comando após o prompt ``sage:`` em uma célula, e
++pressionar shift-enter para calcular o resultado.
++
++::
++
++    sage: 3 + 5
++    8
++
++O acento circunflexo significa "elevar à potência".
++
++::
++
++    sage: 57.1 ^ 100
++    4.60904368661396e175
++
++Pode-se calcular a inversa de uma matrix :math:`2 \times 2` com o Sage.
++
++::
++
++    sage: matrix([[1,2], [3,4]])^(-1)
++    [  -2    1]
++    [ 3/2 -1/2]
++
++A seguir, calculamos a integral de uma função simples.
++
++::
++
++    sage: x = var('x')   # create a symbolic variable
++    sage: integrate(sqrt(x)*sqrt(1+x), x)
++    1/4*((x + 1)^(3/2)/x^(3/2) + sqrt(x + 1)/sqrt(x))/((x + 1)^2/x^2 - 2*(x + 1)/x + 1) + 1/8*log(sqrt(x + 1)/sqrt(x) - 1) - 1/8*log(sqrt(x + 1)/sqrt(x) + 1)
++
++Agora vamos resolver uma equação quadrática com o Sage. O símbolo
++``==`` representa igualdade no Sage.
++
++::
++
++    sage: a = var('a')
++    sage: S = solve(x^2 + x == a, x); S
++    [x == -1/2*sqrt(4*a + 1) - 1/2, x == 1/2*sqrt(4*a + 1) - 1/2]
++
++O resultado é uma lista de igualdades.
++
++.. link
++
++::
++
++    sage: S[0].rhs()
++    -1/2*sqrt(4*a + 1) - 1/2
++    sage: show(plot(sin(x) + sin(1.6*x), 0, 40))
++
++.. image:: sin_plot.*
++
++
++Cálculo Numérico com o Sage
++===========================
++
++Primeiro vamos criar uma matriz :math:`500 \times 500` de números aleatórios.
++
++::
++
++    sage: m = random_matrix(RDF,500)
++
++Leva alguns segundos para calcular os autovalores dessa matriz e
++representá-los em um gráfico.
++
++.. link
++
++::
++
++    sage: e = m.eigenvalues()  #about 2 seconds
++    sage: w = [(i, abs(e[i])) for i in range(len(e))]
++    sage: show(points(w))
++
++.. image:: eigen_plot.*
++
++
++Graças à biblioteca GMP (GNU Multiprecision Library), o Sage pode
++efetuar cálculos com números muito grandes, até mesmo com números com
++milhões de dígitos.
++
++::
++
++    sage: factorial(100)
++    93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
++    sage: n = factorial(1000000)  #about 2.5 seconds
++
++Vamos calcular :math:`\pi` com 100 algarismos decimais.
++
++::
++
++    sage: N(pi, digits=100)
++    3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
++
++Agora o Sage vai fatorar um polinômio em duas variáveis.
++
++::
++
++    sage: R.<x,y> = QQ[]
++    sage: F = factor(x^99 + y^99)
++    sage: F
++    (x + y) * (x^2 - x*y + y^2) * (x^6 - x^3*y^3 + y^6) * 
++    (x^10 - x^9*y + x^8*y^2 - x^7*y^3 + x^6*y^4 - x^5*y^5 +
++     x^4*y^6 - x^3*y^7 + x^2*y^8 - x*y^9 + y^10) * 
++    (x^20 + x^19*y - x^17*y^3 - x^16*y^4 + x^14*y^6 + x^13*y^7 -
++     x^11*y^9 - x^10*y^10 - x^9*y^11 + x^7*y^13 + x^6*y^14 - 
++     x^4*y^16 - x^3*y^17 + x*y^19 + y^20) * (x^60 + x^57*y^3 -
++     x^51*y^9 - x^48*y^12 + x^42*y^18 + x^39*y^21 - x^33*y^27 - 
++     x^30*y^30 - x^27*y^33 + x^21*y^39 + x^18*y^42 - x^12*y^48 -
++     x^9*y^51 + x^3*y^57 + y^60)
++    sage: F.expand()
++    x^99 + y^99
++
++O Sage leva menos de 5 segundos para calcular de quantas maneiras pode-se
++particionar :math:`10^8` como uma soma de inteiros positivos.
++
++::
++
++    sage: z = Partitions(10^8).cardinality() #about 4.5 seconds
++    sage: str(z)[:40]
++    '1760517045946249141360373894679135204009'
++
++Algoritmos incluídos no Sage
++============================
++
++Quando você usa o Sage, você acessa uma das maiores coleções
++disponíveis de algoritmos computacionais de código aberto.
diff --git a/trac_12822_pt_translation_of_tutorial.patch b/trac_12822_pt_translation_of_tutorial.patch
new file mode 100644
index 0000000..4907306
--- /dev/null
+++ b/trac_12822_pt_translation_of_tutorial.patch
@@ -0,0 +1,6801 @@
+# HG changeset patch
+# User Gustavo de Oliveira <goliveira5d at gmail.com>
+# Date 1334006083 -7200
+# Node ID ad8e41651a3187a45f087335cb048418bf545506
+# Parent  bbd101e6eaa8de241270aa8063dc8380a6d983e3
+Trac 12822: Portuguese translation of "Tutorial".
+
+diff --git a/doc/pt/tutorial/afterword.rst b/doc/pt/tutorial/afterword.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/afterword.rst
+@@ -0,0 +1,181 @@
++********
++Posfacio
++********
++
++Por quê o Python?
++=================
++
++Vantagens do Python
++-------------------
++
++A primeira linguagem de implementação do Sage é o Python (veja [Py]_),
++embora rotinas que precisam ser muito rápidas são implementadas em uma
++linguagem compilada. O Python possui várias vantagens:
++
++-  **Salvar objetos** é bem suportado em Python. Existe suporte
++   extenso em Python para salvar (na grande maioria dos casos) objetos
++   arbitrários em arquivos em disco ou em uma base de dados.
++
++-  Suporte excelente para **documentação** de funções e pacotes no
++   código fonte, incluindo extração automática de documentação e teste
++   automático de todos os exemplos. Os exemplos são automaticamente
++   testados regularmente para garantir que funcionam como indicado.
++
++-  **Gerenciamento de memória:** O Python agora possui um sistema de
++   gerenciamento de memória e "garbage collector" muito bem pensados e
++   robustos que lidam corretamente com referências circulares, e
++   permitem variáveis locais em arquivos.
++
++-  O Python possui **diversos pacotes** disponíveis que podem ser de
++   grande interesse para os usuários do Sage: análise numérica e
++   álgebra linear, visualização 2D e 3D, comunicação via rede (para
++   computação distribuída e servidores, por exemplo, via twisted),
++   suporte a base de dados, etc.
++
++-  **Portabilidade:** O Python é fácil de compilar a partir do código
++   fonte em poucos minutos na maioria das arquiteturas.
++
++-  **Manuseamento de exceções:** O Python possui um sofisticado e bem
++   pensado sistema de manuseamento de exceções, através do qual
++   programas podem facilmente se recuperar mesmo se ocorrerem erros no
++   código que está sendo executado.
++
++-  **Debugador:** O Python inclui um debugador, de modo que quando
++   alguma rotina falha por algum motivo, o usuário pode acessar
++   extensiva informação sobre a pilha de cálculos e inspecionar o
++   estado de todas as variáveis relevantes.
++
++-  **Profiler:** Existe um profiler para o Python, o qual executa
++   programas e cria um relatório detalhando quantas vezes e por quando
++   tempo cada função foi executada.
++
++-  **Uma Linguagem:** Em vez de escrever uma **nova linguagem** para
++   matemática como foi feito para o Magma, Maple, Mathematica, Matlab,
++   GP/PARI, GAP, Macaulay 2, Simath, etc., nós usamos a linguagem
++   Python, que é uma linguagem de programação popular que está
++   sendo desenvolvida e otimizada ativamente por centenas de
++   engenheiros de software qualificados. O Python é uma grande
++   história de sucesso em desenvolvimento com código aberto com um
++   processo de desenvolvimento maduro (veja [PyDev]_).
++
++.. _section-mathannoy:
++
++O Pré-Processador: Diferenças entre o Sage e o Python
++-----------------------------------------------------
++
++Alguns aspectos matemáticos do Python podem ser confusos, logo o Sage
++se comporta diferentemente do Python em diversas situações.
++
++-  **Notação para exponenciação:** ``**`` versus ``^``. Em Python,
++   ``^`` significa "xor", não exponenciação, logo em Python temos
++
++   ::
++
++       >>> 2^8
++       10
++       >>> 3^2
++       1
++       >>> 3**2
++       9
++
++   Esse uso de ``^`` pode parecer estranho, e é ineficiente para
++   pesquisa em matemática pura, pois a função "ou exclusivo" é
++   raramente usada. Por conveniência, o Sage pre-processa todos as
++   linhas de comandos antes de passá-las para o Python, substituindo
++   ocorrências de ``^`` que não estão em strings por ``**``:
++
++   ::
++
++       sage: 2^8
++       256
++       sage: 3^2
++       9
++       sage: "3^2"
++       '3^2'
++
++-  **Divisão por inteiros:** A expressão em Python ``2/3`` não se
++   comporta da forma que um matemático esperaria. Em Python, se ``m``
++   e ``n`` são inteiros (int), então ``m/n`` também é um inteiro
++   (int), a saber, o quociente de ``m`` dividido por ``n``. Portanto
++   ``2/3=0``. Tem havido discussões na comunidade do Python para
++   modificar o Python de modo que ``2/3`` retorne um número de
++   precisão flutuante (float) ``0.6666...``, e ``2//3`` retorne ``0``.
++
++   Nós lidamos com isso no interpretador Sage, encapsulando inteiros
++   literais em ``Integer()`` e fazendo a divisão um construtor para
++   números racionais. Por exemplo:
++
++   ::
++
++       sage: 2/3
++       2/3
++       sage: (2/3).parent()
++       Rational Field
++       sage: 2//3
++       0
++       sage: int(2)/int(3)
++       0
++
++-  **Inteiros longos:** O Python possui suporte nativo para inteiros
++   com precisão arbitrária, além de int's do C. Esses são
++   significantemente mais lentos do que os fornecidos pela biblioteca
++   GMP, e têm a propriedade que eles são impressos com o sufixo ``L``
++   para distingui-los de int's (e isso não será modificado no futuro
++   próximo). O Sage implementa inteiros com precisão arbitrária usando
++   a biblioteca C do GMP, e esses são impressos sem o sufixo ``L``.
++
++Em vez de modificar o interpretador Python (como algumas pessoas
++fizeram para projetos internos), nós usamos a linguagem Python
++exatamente com ela é, e escrevemos um pré-processador para o IPython de
++modo que o comportamento da linha de comando seja o que um matemático
++espera. Isso significa que qualquer programa existente em Python pode
++ser usado no Sage. Todavia, deve-se obedecer as regras padrão do
++Python para escrever programas que serão importados no Sage.
++
++(Para instalar uma biblioteca do Python, por exemplo uma que você
++tenha encontrado na internet, siga as instruções, mas execute ``sage
++-python`` em vez de ``python``. Frequentemente isso significa digitar
++``sage -python setup.py install``.)
++
++Eu gostaria de contribuir de alguma forma. Como eu posso?
++=========================================================
++
++Se você quiser contribuir para o Sage, a sua ajuda será muito bem
++vinda! Ela pode variar desde substancial quantidade de código, até
++contribuições com respeito à documentação ou notificação de defeitos
++(bugs).
++
++Explore a página na web do Sage para informações para desenvolvedores;
++entre outras coisas, você pode encontrar uma lista longa de projetos
++relacionados ao Sage ordenados por prioridade e categoria. O `Guia
++para desenvolvedores do Sage
++<http://www.sagemath.org/doc/developer/>`_ (em inglês) também possui
++informações úteis, e você pode também visitar o grupo de discussões
++``sage-devel`` no Google Groups.
++
++Como eu faço referência ao Sage?
++================================
++
++Se você escrever um artigo usando o Sage, por favor faça referência
++aos cálculos feitos com o Sage incluindo
++
++::
++
++    [Sage] William A. Stein et al., Sage Mathematics Software (Version 4.3).
++           The Sage Development Team, 2009, http://www.sagemath.org.
++
++na sua bibliografia (substituindo 4.3 pela versão do Sage que você
++está usando). Além disso, procure observar quais componentes do Sage
++você está usando em seus cálculos, por exemplo, PARI, Singular, GAP,
++Maxima, e também site esses sistemas. Se você está em dúvida sobre
++qual software está sendo usado em seus cálculos, fique à vontade para
++perguntar no grupo ``sage-devel`` do Google Groups. Veja
++:ref:`section-univariate` para mais discussões sobre esse aspecto.
++
++------------
++
++Se por acaso você leu este tutorial do começo ao fim em uma só vez, e
++faz idéia de quanto tempo você levou, por favor nos informe no grupo
++``sage-devel`` do Google Groups.
++
++Divirta-se com o Sage!
+diff --git a/doc/pt/tutorial/appendix.rst b/doc/pt/tutorial/appendix.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/appendix.rst
+@@ -0,0 +1,33 @@
++********
++Apêndice
++********
++
++.. _section-precedence:
++
++Precedência de operações aritméticas binárias
++=============================================
++
++Quanto é ``3^2*4 + 2%5``? A resposta (38) é determinada pela "tabela
++de precedência" abaixo. A tabela abaixo é baseada na tabela em § 5.14
++do *Python Language Reference Manual* by G. Rossum and F. Drake. As
++operações estão listadas aqui em ordem crescente de precedência.
++
++
++==========================  =================
++Operadores                  Descrição
++==========================  =================
++or                          "ou" booleano
++and  	     		        "e" booleano
++not	     		            "não" booleano
++in, not in   		        pertence
++is, is not   		        teste de identidade
++>, <=, >, >=, ==, !=, <>    comparação
+++, -                        adição, subtração
++\*, /, %                    multiplicação, divisão, resto
++\*\*, ^                     exponenciação
++==========================  =================
++
++Portanto, para calcular ``3^2*4 + 2%5``, O Sage inclui parenteses de
++precedência da seguinte forma: ``((3^2)*4) + (2%5)``. Logo, primeiro
++calcula ``3^2``, que é ``9``, então calcula ``(3^2)*4`` e ``2%5``, e
++finalmente soma os dois.
+diff --git a/doc/pt/tutorial/bibliography.rst b/doc/pt/tutorial/bibliography.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/bibliography.rst
+@@ -0,0 +1,52 @@
++************
++Bibliografia
++************
++
++..  [Cyt] Cython, http://www.cython.org.
++
++..  [Dive] Dive into Python, disponível gratuitamente na internet em
++    http://diveintopython.org.
++
++..  [GAP] The GAP Group, GAP - Groups, Algorithms, and
++    Programming, Version 4.4; 2005, http://www.gap-system.org
++
++..  [GAPkg] GAP Packages,
++    http://www.gap-system.org/Packages/packages.html
++
++..  [GP] PARI/GP http://pari.math.u-bordeaux.fr/.
++
++..  [Ip] The IPython shell http://ipython.scipy.org.
++
++..  [Jmol] Jmol: an open-source Java viewer for chemical
++    structures in 3D http://www.jmol.org/.
++
++..  [Mag] Magma http://magma.maths.usyd.edu.au/magma/.
++
++..  [Max] Maxima http://maxima.sf.net/
++
++..  [NagleEtAl2004] Nagle, Saff, and Snider.
++    *Fundamentals of Differential Equations*. 6th edition, Addison-Wesley,
++    2004.
++
++..  [Py] The Python language http://www.python.org/
++    Reference Manual http://docs.python.org/ref/ref.html.
++
++..  [PyDev] Guido, Some Guys, and a Mailing List: How Python is
++    Developed,
++    http://www.python.org/dev/dev_intro.html.
++
++..  [Pyr] Pyrex,
++    http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/.
++
++..  [PyT] The Python Tutorial http://www.python.org/.
++
++..  [SA] Sage web site http://www.sagemath.org/.
++
++..  [Si] G.-M. Greuel, G. Pfister, and H. Schönemann. Singular
++    3.0. A Computer Algebra System for Polynomial Computations. Center
++    for Computer Algebra, University of Kaiserslautern (2005).
++    http://www.singular.uni-kl.de.
++
++..  [SJ] William Stein, David Joyner, Sage: System for Algebra and
++    Geometry Experimentation, Comm. Computer Algebra {39}(2005)61-64.
++
+diff --git a/doc/pt/tutorial/conf.py b/doc/pt/tutorial/conf.py
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/conf.py
+@@ -0,0 +1,35 @@
++# -*- coding: utf-8 -*-
++#
++# Sage documentation build configuration file, based on the file created by
++# sphinx-quickstart on Thu Aug 21 20:15:55 2008.
++#
++# This file is execfile()d with the current directory set to its containing dir.
++#
++# The contents of this file are pickled, so don't put values in the namespace
++# that aren't pickleable (module imports are okay, they're removed automatically).
++#
++# All configuration values have a default; values that are commented out
++# serve to show the default.
++
++import sys, os
++sys.path.append(os.environ['SAGE_DOC'])
++from common.conf import *
++
++# General information about the project.
++project = u"Tutorial Sage"
++name = u'tutorial-pt'
++language = "pt_BR"
++
++# The name for this set of Sphinx documents.  If None, it defaults to
++# "<project> v<release> documentation".
++html_title = project + " v"+release
++
++# Output file base name for HTML help builder.
++htmlhelp_basename = name
++
++# Grouping the document tree into LaTeX files. List of tuples
++# (source start file, target name, title, author, document class [howto/manual]).
++latex_documents = [
++  ('index', name+'.tex', project,
++   u'The Sage Group', 'manual'),
++]
+diff --git a/doc/pt/tutorial/index.rst b/doc/pt/tutorial/index.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/index.rst
+@@ -0,0 +1,46 @@
++.. Sage documentation master file, created by sphinx-quickstart on Thu Aug 21 20:15:55 2008.
++   You can adapt this file completely to your liking, but it should at least
++   contain the root `toctree` directive.
++
++Bem-vindo ao Tutorial Sage!
++===========================
++
++Sage é um software de matemática gratuito, de código aberto, para uso
++em ensino e pesquisa em álgebra, geometria, teoria de números,
++criptografia, computação numérica, e áreas relacionadas. Tanto o
++modelo de desenvolvimento como a tecnologia empregada no Sage se
++distinguem pela forte ênfase em transparência, cooperação, e
++colaboração: estamos desenvolvendo o carro, não reinventando a roda. O
++objetivo maior do Sage é criar uma alternativa viável, gratuita, e de
++código aberto aos programas Maple, Mathematica, Magma e MATLAB.
++
++Este tutorial é a melhor forma de se familiarizar com o Sage em apenas
++algumas horas. Você pode lê-lo em versão HTML ou PDF, ou diretamente
++no Notebook Sage (clique em ``Help``, e então clique em ``Tutorial``
++para percorrer o tutorial de forma iterativa diretamente do Sage).
++
++Este documento está sob a licença `Creative Commons CompartilhaIgual
++3.0`__.
++
++__ http://creativecommons.org/licenses/by-sa/3.0/deed.pt
++
++.. toctree::
++   :maxdepth: 2
++
++   introduction
++   tour
++   interactive_shell
++   interfaces
++   latex
++   programming
++   sagetex
++   afterword
++   appendix
++   bibliography
++
++Índices e tabelas 
++=================
++
++* :ref:`genindex`
++* :ref:`modindex`
++* :ref:`search`
+diff --git a/doc/pt/tutorial/interactive_shell.rst b/doc/pt/tutorial/interactive_shell.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/interactive_shell.rst
+@@ -0,0 +1,1024 @@
++.. _chapter-interactive_shell:
++
++*****************************
++A Linha de Comando Interativa
++*****************************
++Na maior parte deste tutorial, assumimos que você iniciou o
++interpretador Sage usando o comando ``sage``. Isso inicia uma versão
++personalizada da linha de comando IPython, e importa diversas funções
++e classes de modo que elas fiquem prontas para serem usadas a partir
++da linha de comando. Configuração adicional é possível editando o
++arquivo ``$SAGE_ROOT/ipythonrc``. Assim que você inicia o Sage, você
++obtém o seguinte:
++
++.. skip
++
++::
++
++    ----------------------------------------------------------------------
++    | SAGE Version 3.1.1, Release Date: 2008-05-24                       |
++    | Type notebook() for the GUI, and license() for information.        |
++    ----------------------------------------------------------------------
++    sage:
++
++Para sair do Sage pressione Ctrl-D ou digite ``quit`` ou ``exit``.
++
++.. skip
++
++::
++
++    sage: quit
++    Exiting SAGE (CPU time 0m0.00s, Wall time 0m0.89s)
++
++O wall time é o tempo que passou no relógio "pendurado na sua parede".
++Isso é relevante, pois o tempo CPU não conta o tempo usado por
++subprocessos como GAP ou Singular.
++
++(Evite terminar um processo do Sage usando ``kill -9`` a partir de um
++terminal, pois o Sage pode não terminal seus subprocessos, por
++exemplo, subprocessos do Maple, ou limpeza de arquivos temporários em 
++``$HOME/.sage/tmp``.)
++
++A Sua Sessão no Sage
++====================
++
++A sessão é a sequência de entradas e saídas de dados desde o momento em
++que você inicia até o momento em que você termina o Sage. O Sage grava
++todas as entradas de dados, através do IPython. De fato, se você está
++usando a linha de comando (não o Notebook), então a qualquer momento
++você pode digitar ``%history`` (ou ``%hist``) para obter uma lista de
++todas as linhas digitadas até então. Você pode digitar ``?`` no prompt
++do Sage para aprender mais sobre o IPython, por exemplo, "IPython
++offers numbered prompts ... with input and output caching. All input
++is saved and can be retrieved as variables (besides the usual arrow
++key recall). The following GLOBAL variables always exist (so don't
++overwrite them!)":
++
++::
++
++      _:  previous input (interactive shell and notebook)
++      __: next previous input (interactive shell only)
++      _oh : list of all inputs (interactive shell only)
++
++Aqui vai um exemplo:
++
++.. skip
++
++::
++
++    sage: factor(100)
++     _1 = 2^2 * 5^2
++    sage: kronecker_symbol(3,5)
++     _2 = -1
++    sage: %hist   #This only works from the interactive shell, not the notebook.
++    1: factor(100)
++    2: kronecker_symbol(3,5)
++    3: %hist
++    sage: _oh
++     _4 = {1: 2^2 * 5^2, 2: -1}
++    sage: _i1
++     _5 = 'factor(ZZ(100))\n'
++    sage: eval(_i1)
++     _6 = 2^2 * 5^2
++    sage: %hist
++    1: factor(100)
++    2: kronecker_symbol(3,5)
++    3: %hist
++    4: _oh
++    5: _i1
++    6: eval(_i1)
++    7: %hist
++
++Vamos omitir a numeração das linhas no restante deste tutorial e em
++outras documentações do Sage.
++
++Você também pode salvar uma lista de comandos em uma macro.
++
++.. skip
++
++::
++
++    sage: E = EllipticCurve([1,2,3,4,5])
++    sage: M = ModularSymbols(37)
++    sage: %hist
++    1: E = EllipticCurve([1,2,3,4,5])
++    2: M = ModularSymbols(37)
++    3: %hist
++    sage: %macro em 1-2
++    Macro `em` created. To execute, type its name (without quotes).
++
++
++.. skip
++
++::
++
++    sage: E
++    Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over 
++    Rational Field
++    sage: E = 5
++    sage: M = None
++    sage: em
++    Executing Macro...
++    sage: E
++    Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over 
++    Rational Field
++
++Quando se usa a linha de comando, qualquer comando UNIX pode ser
++executado a partir do Sage inserindo um ponto de exclamação ``!`` como
++prefixo. Por exemplo,
++
++.. skip
++
++::
++
++    sage: !ls
++    auto  example.sage glossary.tex  t  tmp  tut.log  tut.tex
++
++fornece a lista de arquivos do atual diretório.
++
++O ``PATH`` possui o diretório bin do Sage em primeiro, portanto se
++você digitar ``p``, ``gap``, ``singular``, ``maxima``, etc., você
++executa a versão incluída no Sage.
++
++.. skip
++
++::
++
++    sage: !gp
++    Reading GPRC: /etc/gprc ...Done.
++    
++                               GP/PARI CALCULATOR Version 2.2.11 (alpha)
++                      i686 running linux (ix86/GMP-4.1.4 kernel) 32-bit version
++    ...
++    sage: !singular
++                         SINGULAR                             /  Development
++     A Computer Algebra System for Polynomial Computations   /   version 3-0-1
++                                                           0<
++         by: G.-M. Greuel, G. Pfister, H. Schoenemann        \   October 2005
++    FB Mathematik der Universitaet, D-67653 Kaiserslautern    \
++
++Gravando Entradas e Saídas de dados
++===================================
++
++Gravar a sua sessão no Sage não é o mesmo que salvá-la (veja
++:ref:`section-save`). Para gravar a entrada de dados (e opcionalmente
++a saída) use o comando ``logstart``. Digite ``logstart?`` para mais
++detalhes. Você pode usar esse comando para gravar tudo o que você
++digita, toda a saída de dados, e até mesmo usar essa entrada de dados
++que você guardou em uma sessão futura (simplesmente importando o
++arquivo log).
++
++.. skip
++
++::
++
++    was at form:~$ sage
++    ----------------------------------------------------------------------
++    | SAGE Version 3.0.2, Release Date: 2008-05-24                       |
++    | Type notebook() for the GUI, and license() for information.        |
++    ----------------------------------------------------------------------
++    
++    sage: logstart setup
++    Activating auto-logging. Current session state plus future input saved.
++    Filename       : setup
++    Mode           : backup
++    Output logging : False
++    Timestamping   : False
++    State          : active
++    sage: E = EllipticCurve([1,2,3,4,5]).minimal_model()
++    sage: F = QQ^3
++    sage: x,y = QQ['x,y'].gens()
++    sage: G = E.gens()
++    sage:
++    Exiting SAGE (CPU time 0m0.61s, Wall time 0m50.39s).
++    was at form:~$ sage
++    ----------------------------------------------------------------------
++    | SAGE Version 3.0.2, Release Date: 2008-05-24                       |
++    | Type notebook() for the GUI, and license() for information.        |
++    ----------------------------------------------------------------------
++    
++    sage: load "setup"
++    Loading log file <setup> one line at a time...
++    Finished replaying log file <setup>
++    sage: E
++    Elliptic Curve defined by y^2 + x*y  = x^3 - x^2 + 4*x + 3 over Rational 
++    Field
++    sage: x*y
++    x*y
++    sage: G
++    [(2 : 3 : 1)]
++
++Se você usa o Sage no terminal ``konsole`` do Linux KDE, então você
++pode gravar a sessão da seguinte forma: após iniciar o Sage no
++``konsole``, selecione "settings", então "history...", então "set
++unlimited". Quando você estiver pronto para guardar a sua sessão,
++selecione "edit" e então "save history as..." e digite um nome para
++salvar o texto de sua sessão em seu computador. Após salvar esse
++arquivo, você poderia abri-lô em um editor, tal como o xemacs, e
++imprimi-lo.
++
++Colar Texto Ignora Prompts
++==========================
++
++Suponha que você está lendo uma sequência de comandos em Sage ou
++Python e quer copiá-los no Sage. Mas eles têm os irritantes prompts
++``>>>`` ou ``sage:`` para te aborrecer. De fato, você pode copiar e
++colar um exemplo, incluindo os prompts se você quiser, no Sage. Em
++outras palavras, automaticamente o Sage remove os caracteres ``>>>``
++ou ``sage:`` antes de colar o conteúdo no Python. Por exemplo,
++
++.. skip
++
++::
++
++    sage: 2^10
++    1024
++    sage: sage: sage: 2^10
++    1024
++    sage: >>> 2^10
++    1024
++
++Comandos de Tempo
++=================
++
++Se você colocar o comando ``%time`` no começo de uma linha de comando,
++o tempo que o comando leva para ser executado vai aparecer após a
++saída de dados. Por exemplo, nós podemos comparar o tempo de execução
++para certas operações de exponenciação de várias formas. Os tempos
++abaixo vão ser provavelmente muito diferentes para o seu computador,
++ou até mesmo para versões diferentes do Sage. Primeiro, usando o
++Python
++
++.. skip
++
++::
++
++    sage: %time a = int(1938)^int(99484)
++    CPU times: user 0.66 s, sys: 0.00 s, total: 0.66 s
++    Wall time: 0.66
++
++Isso significa que levou 0.66 segundos no total, e o wall time, isto
++é, a quantidade de tempo que passou no seu relógio de parede, é também
++0.66 segundos. Se o seu computador está executado outros programas o
++wall time pode ser muito maior do que o tempo de CPU.
++
++A seguir verificamos o tempo de exponenciação usando o tipo Integer do
++Sage, o qual é implementado (em Cython) usando a biblioteca GMP:
++
++.. skip
++
++::
++
++    sage: %time a = 1938^99484
++    CPU times: user 0.04 s, sys: 0.00 s, total: 0.04 s
++    Wall time: 0.04
++
++Usando a biblioteca C do PARI:
++
++.. skip
++
++::
++
++    sage: %time a = pari(1938)^pari(99484)
++    CPU times: user 0.05 s, sys: 0.00 s, total: 0.05 s
++    Wall time: 0.05
++
++A GMP é melhor, mas por pouco (como esperado, pois a versão do PARI
++contida no Sage usa a GMP para aritmética de inteiros).
++
++Você pode também contar o tempo de um bloco de comandos usado o
++comando ``cputime``, como ilustrado abaixo:
++
++::
++
++    sage: t = cputime()
++    sage: a = int(1938)^int(99484)
++    sage: b = 1938^99484
++    sage: c = pari(1938)^pari(99484)
++    sage: cputime(t)                       # somewhat random output
++    0.64                                     
++
++.. skip
++
++::
++
++    sage: cputime?
++    ...
++        Return the time in CPU second since SAGE started, or with optional
++        argument t, return the time since time t.
++        INPUT:
++            t -- (optional) float, time in CPU seconds
++        OUTPUT:
++            float -- time in CPU seconds
++
++O comando ``walltime`` se comporta como o comando ``cputime``, exceto
++que ele conta o tempo do relógio.
++
++Nós podemos também calcular a potência acima em alguns softwares de
++álgebra incluídos no Sage. Em cada caso executamos um comando trivial
++no sistema de modo a inicializar o servidor para aquele programa. O
++tempo mais relevante é o tempo do relógio. Todavia, se houver uma
++diferença significativa entre o wall time e o CPU time então isso pode
++indicar algum problema de performance que vale a pena investigar.
++
++.. skip
++
++::
++
++    sage: time 1938^99484;
++    CPU times: user 0.01 s, sys: 0.00 s, total: 0.01 s
++    Wall time: 0.01
++    sage: gp(0)
++    0
++    sage: time g = gp('1938^99484')
++    CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
++    Wall time: 0.04
++    sage: maxima(0)
++    0
++    sage: time g = maxima('1938^99484')
++    CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
++    Wall time: 0.30
++    sage: kash(0)
++    0
++    sage: time g = kash('1938^99484')
++    CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
++    Wall time: 0.04
++    sage: mathematica(0)
++            0
++    sage: time g = mathematica('1938^99484')
++    CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
++    Wall time: 0.03
++    sage: maple(0)
++    0
++    sage: time g = maple('1938^99484')
++    CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
++    Wall time: 0.11
++    sage: gap(0)
++    0
++    sage: time g = gap.eval('1938^99484;;')
++    CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
++    Wall time: 1.02
++
++Note que o GAP e o Maxima são os mais lentos neste teste (isso foi
++executado no computador ``sage.math.washington.edu``). Devido ao
++"overhead" da interface pexpect, talvez não seja apropriado comparar
++esses resultados com o Sage, que é o mais rápido.
++
++Outras Dicas para o IPython
++===========================
++
++Como observado acima, o Sage usa o IPython como interface, logo você
++pode usar quaisquer comandos e recursos do IPython. Você pode ler a
++`Documentação completa do IPython
++<http://ipython.scipy.org/moin/Documentation>`_ (em inglês).
++
++- Você pode usar ``%bg`` para executar um comando no background, e
++  então usar ``jobs`` para acessar os resultados, da seguinte forma.
++  (Os comentários ``not tested`` estão aqui porque a sintaxe ``%bg``
++  não funciona bem com o sistema de testes automáticos do Sage. Se
++  você digitar esses comandos, eles devem funcionar. Isso é obviamente
++  mais útil com comandos que demoram para serem completados.)
++
++  ::
++
++    sage: def quick(m): return 2*m
++    sage: %bg quick(20)  # not tested
++    Starting job # 0 in a separate thread.
++    sage: jobs.status()  # not tested
++    Completed jobs:
++    0 : quick(20)
++    sage: jobs[0].result  # the actual answer, not tested
++    40
++
++  Note que os comandos executados no background não usam o
++  pre-processador (preparser) do Sage -- veja :ref:`section-mathannoy`
++  para mais informações. Uma forma (estranha talvez) de contornar esse
++  problema seria executar ::
++
++    sage: %bg eval(preparse('quick(20)')) # not tested
++
++  É mais seguro e simples, todavia, usar ``%bg`` apenas em comandos
++  que não requerem o pre-processador (preparser).
++
++- Você pode usar ``%edit`` (ou ``%ed`` ou ``ed``) para abrir um
++  editor, se você desejar digitar algum código mais complexo. Antes de
++  iniciar o Sage, certifique-se de que a variável de environment
++  :envvar:`EDITOR` está definida com o seu editor favorito (colocando
++  ``export EDITOR=/usr/bin/emacs`` ou ``export EDITOR=/usr/bin/vim``
++  or algo similar no lugar apropriado, como um arquivo ``.profile``).
++  A partir do prompt do Sage, o comando ``%edit`` irá abrir o editor
++  escolhido. Então usando o editor você pode definir uma função::
++
++    def some_function(n):
++        return n**2 + 3*n + 2
++
++  Salve e feche o editor. No restante da sua sessão do Sage, você pode
++  usar então a função ``some_function``. Se você quiser modificá-la,
++  digite ``%edit some_function`` no prompt do Sage.
++
++- Se você for calcular algo e quiser modificar o resultado para outro
++  uso, execute o cálculo e então digite ``%rep``: isso irá colocar o
++  resultado do comando anterior no prompt do Sage, pronto para ser
++  editado.::
++
++    sage: f(x) = cos(x)
++    sage: f(x).derivative(x)
++    -sin(x)
++
++  A esta altura, se você digitar ``%rep`` no prompt do Sage, você irá
++  obter um novo prompt, seguido de ``-sin(x)``, com o cursor no final
++  da linha.
++
++Para mais informações, digite ``%quickref`` para ver um guia rápido de
++referência do IPython. Quando este tutorial foi escrito (April 2011),
++o Sage usa a versão 0.9.1 do IPython, e a `documentation for its magic
++commands <http://ipython.scipy.org/doc/rel-0.9.1/html/interactive/reference.html#magic-commands>`_
++está disponível na internet.
++
++
++Erros e Exceções
++================
++
++Quando algo errado ocorre, você usualmente verá uma "exceção" do
++Python. O Python até mesmo tenta sugerir o que ocasionou a exceção,
++por exemplo, ``NameError`` ou ``ValueError`` (veja o Manual de
++Referência do Python [Py]_ para uma lista completa de exceções). Por
++exemplo,
++
++.. skip
++
++::
++
++    sage: 3_2
++    ------------------------------------------------------------
++       File "<console>", line 1
++         ZZ(3)_2
++               ^
++    SyntaxError: invalid syntax
++    
++    sage: EllipticCurve([0,infinity])
++    ------------------------------------------------------------
++    Traceback (most recent call last):
++    ...
++    TypeError: Unable to coerce Infinity (<class 'sage...Infinity'>) to Rational
++
++O debugador interativo é as vezes útil para entender o que houve de
++errado. Você pode ativá-lo e desativá-lo usando ``%pdb`` (o padrão é
++desativado). O prompt ``ipdb>`` aparece se uma exceção é levantada e o
++debugador está ativado. A partir do debugador, você pode imprimir o
++estado de qualquer variável local, e mover a pilha de execução para
++cima e para baixo. Por exemplo,
++
++.. skip
++
++::
++
++    sage: %pdb
++    Automatic pdb calling has been turned ON
++    sage: EllipticCurve([1,infinity])
++    ---------------------------------------------------------------------------
++    <type 'exceptions.TypeError'>             Traceback (most recent call last)
++    ...
++    
++    ipdb> 
++
++Para uma lista de comandos do debugador, digite ``?`` no prompt
++``ipbd>``:
++
++::
++
++    ipdb> ?
++    
++    Documented commands (type help <topic>):
++    ========================================
++    EOF    break  commands   debug    h       l     pdef   quit    tbreak   
++    a      bt     condition  disable  help    list  pdoc   r       u      
++    alias  c      cont       down     ignore  n     pinfo  return  unalias
++    args   cl     continue   enable   j       next  pp     s       up
++    b      clear  d          exit     jump    p     q      step    w
++    whatis where
++    
++    Miscellaneous help topics:
++    ==========================
++    exec  pdb
++    
++    Undocumented commands:
++    ======================
++    retval  rv
++
++Digite Ctrl-D ou ``quit`` para retornar ao Sage.
++
++.. _section-tabcompletion:
++
++Busca Reversa e Completamento Tab
++==================================
++
++Busca reversa: Digite o começo de um comando, e então ``Ctrl-p`` (ou
++tecle a seta para cima) para voltar para cada linha que você digitou
++que começa daquela forma. Isso funciona mesmo se você encerrou o Sage
++e iniciou novamente mais tarde. Você também pode fazer uma busca
++reversa ao longo da história usando ``Ctrl-r``. Todos esses recursos
++usam o pacote ``readline``, que está disponível no Linux.
++
++Para ilustrar a busca reversa, primeiro crie o e espaço vetorial
++tri-dimensional :math:`V=\QQ^3` da seguinte forma:
++
++::
++
++    sage: V = VectorSpace(QQ,3)
++    sage: V              
++    Vector space of dimension 3 over Rational Field
++
++Você pode usar a seguinte notação mais compacta:
++
++::
++
++    sage: V = QQ^3
++
++Então é fácil listar todas as funções para :math:`V` usando
++completamento. Digite ``V``, e então pressione a tecla ``[tab]`` no
++seu teclado:
++
++.. skip
++
++::
++
++    sage: V.[tab key]
++    V._VectorSpace_generic__base_field
++    ...
++    V.ambient_space
++    V.base_field
++    V.base_ring
++    V.basis
++    V.coordinates
++    ...
++    V.zero_vector
++
++Se você digitar as primeiras letras de uma função, e então a tecla
++``[tab]``, você obtém apenas funções que começam conforme indicado.
++
++.. skip
++
++::
++
++    sage: V.i[tab key]
++    V.is_ambient  V.is_dense    V.is_full     V.is_sparse
++
++Se você gostaria de saber o que uma função faz, por exemplo, a função
++coordinates, digite ``V.coordinates?`` para ajuda ou
++``V.coordinates??`` para ver o código fonte, como explicado na próxima
++sessão.
++
++
++
++Sistema de Ajuda Integrado
++==========================
++
++O Sage possui um sistema de ajuda integrado. Digite o nome da função
++seguido de ? para ver informações sobre a função.
++
++.. skip
++
++::
++
++    sage: V = QQ^3
++    sage: V.coordinates?
++    Type:           instancemethod
++    Base Class:     <type 'instancemethod'>
++    String Form:    <bound method FreeModule_ambient_field.coordinates of Vector 
++    space of dimension 3 over Rational Field>
++    Namespace:      Interactive
++    File:           /home/was/s/local/lib/python2.4/site-packages/sage/modules/f
++    ree_module.py
++    Definition:     V.coordinates(self, v)
++    Docstring:
++        Write v in terms of the basis for self.
++    
++        Returns a list c such that if B is the basis for self, then
++    
++                sum c_i B_i = v.
++    
++        If v is not in self, raises an ArithmeticError exception.
++    
++        EXAMPLES:
++            sage: M = FreeModule(IntegerRing(), 2); M0,M1=M.gens()
++            sage: W = M.submodule([M0 + M1, M0 - 2*M1])
++            sage: W.coordinates(2*M0-M1)
++            [2, -1]
++
++Como mostrado acima, o comando de ajuda mostra o tipo do objeto, o
++arquivo no qual ele é definido, e uma descrição útil da função com
++exemplos que você pode colar na sua sessão atual. Quase todos esses
++exemplos são regularmente testados automaticamente para certificar que
++eles se comportam exatamente como esperado.
++
++Outro recurso que vai muito na direção do espírito de código aberto do
++Sage é que se ``f`` é uma função do Python, então o comando ``f??``
++mostra o código fonte que define ``f``. Por exemplo,
++
++.. skip
++
++::
++
++    sage: V = QQ^3
++    sage: V.coordinates??
++    Type:           instancemethod
++    ...
++    Source:
++    def coordinates(self, v):
++            """
++            Write $v$ in terms of the basis for self.
++            ...
++            """
++            return self.coordinate_vector(v).list()
++
++Isso nos diz que tudo que a função ``coordinates`` faz é chamar a
++função ``coordinate_vector`` e converter o resultado para uma lista. O
++que a função ``coordinate_vector`` faz?
++
++.. skip
++
++::
++
++    sage: V = QQ^3
++    sage: V.coordinate_vector??
++    ...
++    def coordinate_vector(self, v):
++            ...
++            return self.ambient_vector_space()(v)
++
++A função ``coordinate_vector`` coage a sua entrada em um espaço
++ambiente, o que tem o efeito de calcular o vetor de coeficientes de
++:math:`v` em termos de :math:`V`. O espaço :math:`V` já é o espaço
++ambiente pois é simplesmente :math:`\QQ^3`. Existe também uma função
++``coordinate_vector`` para subespaços, que é diferente. Vamos criar um
++subespaço e ver:
++
++.. skip
++
++::
++
++    sage: V = QQ^3; W = V.span_of_basis([V.0, V.1])
++    sage: W.coordinate_vector??
++    ...
++    def coordinate_vector(self, v):
++            """
++             ...
++            """
++            # First find the coordinates of v wrt echelon basis.
++            w = self.echelon_coordinate_vector(v)
++            # Next use transformation matrix from echelon basis to
++            # user basis.
++            T = self.echelon_to_user_matrix()
++            return T.linear_combination_of_rows(w)
++
++(Se você acha que a implementação é ineficiente, por favor junte-se a
++nós para ajudar a optimizar as funções de álgebra linear.)
++
++Você também pode digitar ``help(command_name)`` ou ``help(class)``
++para ler um arquivo de ajuda sobre determinada classe.
++
++.. skip
++
++::
++
++    sage: help(VectorSpace)
++    Help on class VectorSpace ...
++    
++    class VectorSpace(__builtin__.object)
++     |  Create a Vector Space.
++     |
++     |  To create an ambient space over a field with given dimension
++     |  using the calling syntax ...
++     :
++     : 
++
++Quando você digita ``q`` para sair do sistema de ajuda, a sua sessão
++aparece na tela da mesma forma que anteriormente. O texto de ajuda não
++fica permanentemente em sua tela, ao contrário da saída de
++``function_name?`` que as vezes fica. É partircularmente útil digitar
++``help(module_name)``. Por exemplo, espaços vetoriais são definidos em
++``sage.modules.free_module``, então digite
++``help(sage.modules.free_module)`` para obter documentação sobre esse
++módulo. Quando visualizando documentação usando a ajuda, você pode
++procurar no texto digitando ``/`` e na ordem reversa digitando ``?``.
++
++Salvando e Carregando Objetos Individuais
++=========================================
++
++Suponha que você calcule uma matriz, ou pior ainda, um espaço
++complicado de símbolos, e gostaria de salvá-los para uso posterior. O
++que você pode fazer? Existem várias estratégias que os sistemas
++computacionais de álgebra adotam para salvar objetos individuais.
++
++#. **Salve seus cálculos:** Suportam apenas salvar e carregar uma
++   sessão completa (por exemplo, GAP, Magma).
++
++#. **Entrada e Saída Unificadas:** Faz com que cada objeto seja
++   impresso de uma forma que possa ser lido novamente (GP/PARI).
++
++#. **Eval:** Torna fácil processar um código arbitrário no
++   interpretador (por exemplo, Singular, PARI).
++
++
++
++Como o Sage usa o Python, ele adota uma estratégia diferente, que se
++baseia no fato de que qualquer objeto pode ser "serializado", isto é,
++transformado em uma string a partir da qual o objeto pode ser
++recuperado. Isso segue o espírito da estratégia unificada de entrada e
++saída do PARI, exceto que não possue a desvantagem que os objetos são
++impressos na tela em uma forma muito complicada. Além disso, o suporte
++para salvar e recuperar é (na maior parte dos casos) completamente
++automática, não requerendo nenhuma programação extra; é simplesmente um
++recurso do Python que foi implementado na linguagem desde o início de
++seu desenvolvimento.
++
++Quase todos os objetos ``x`` podem ser armazenados em disco de forma
++comprimida usando ``save(x, filename)`` (ou em muitos casos
++``x.save(filename)``). Para carregar o objeto de volta no Sage use
++``load(filename)``.
++
++.. skip
++
++::
++
++    sage: A = MatrixSpace(QQ,3)(range(9))^2
++    sage: A
++    [ 15  18  21]
++    [ 42  54  66]
++    [ 69  90 111]
++    sage: save(A, 'A')
++
++Você deve agora sair do Sage e reiniciá-lo. Então você pode obter
++``A`` de volta:
++
++.. skip
++
++::
++
++    sage: A = load('A')
++    sage: A
++    [ 15  18  21]
++    [ 42  54  66]
++    [ 69  90 111]
++
++Você pode fazer o mesmo com objetos mais complicados, por exemplo,
++curvas elípticas. Todos os dados sobre o objeto são guardados e
++restaurados com o objeto. Por exemplo,
++
++.. skip
++
++::
++
++    sage: E = EllipticCurve('11a')
++    sage: v = E.anlist(100000)              # takes a while
++    sage: save(E, 'E')
++    sage: quit
++
++A versão em disco de ``E`` ocupa 153 kilobytes, pois ela guarda os
++primeiros 1000000 :math:`a_n` com ela.
++
++.. skip
++
++::
++
++    ~/tmp$ ls -l E.sobj
++    -rw-r--r--  1 was was 153500 2006-01-28 19:23 E.sobj
++    ~/tmp$ sage [...]
++    sage: E = load('E')
++    sage: v = E.anlist(100000)              # instant!
++
++(Em Python, salvar e restaurar é feito usando o módulo ``cPickle``. Em
++particular, um objeto ``x`` do Sage pode ser salvado usando
++``cPickle.dumps(x, 2)``. Note o ``2``!)
++
++O sage não pode salvar e carregar objetos criados em algum outro
++sistema computacional de álgebra, por exemplo, GAP, Singular, Maxima,
++etc. Eles são carregados em um estado "inválido". Em GAP, embora
++muitos objetos podem ser impressos de uma forma que eles podem ser
++reconstruídos, muitos não, logo reconstrução a partir de suas
++representações impressas não é permitido.
++
++.. skip
++
++::
++
++    sage: a = gap(2)
++    sage: a.save('a')
++    sage: load('a')
++    Traceback (most recent call last):
++    ...
++    ValueError: The session in which this object was defined is no longer 
++    running.
++
++Objetos do GP/PARI também podem ser salvados e carregados pois suas
++representações em forma impressa são suficientes para reconstruí-los.
++
++.. skip
++
++::
++
++    sage: a = gp(2)      
++    sage: a.save('a')
++    sage: load('a')
++    2
++
++Objetos que foram salvados podem ser abertos posteriormente em
++computadores com arquiteturas e sistemas operacionais diferentes, por
++exemplo, você poderia salvar uma matriz muito grande em um OS X de
++32-bits e abri-lo em um Linux de 64-bits, encontrar a forma reduzida,
++e movê-lo de volta. Além disso, em muitos casos você pode até mesmo
++abrir objetos em versões do Sage diferentes daquela no qual o objeto
++foi salvo, desde que o código para aquele objeto não seja muito
++diferente. Todos os atributos do objetos são armazendos, assim como a
++classe (mas não o código fonte) que define o objeto. Se aquela classe
++não existir mais em uma nova versão do Sage, então o objeto não pode
++ser reaberto nessa versão. Mas você poderia abri-lo em uma versão mais
++antiga, obter o dicionário do objeto (com ``x.__dict__``), salvar o
++dicionário, e abri-lo em uma versão mais nova.
++
++Salvando como Texto
++-------------------
++
++Você também pode salvar a representação em texto (ASCII) de objetos em
++um arquivo, simplesmente abrindo um arquivo em modo de escrita, e
++escrevendo a string que representa o objeto no arquivo (você pode
++salvar mais de um objeto dessa forma). Quando você terminar de
++escrever os objetos, feche o arquivo.
++
++.. skip
++
++::
++
++    sage: R.<x,y> = PolynomialRing(QQ,2)
++    sage: f = (x+y)^7
++    sage: o = open('file.txt','w')
++    sage: o.write(str(f))
++    sage: o.close()
++
++.. _section-save:
++
++Salvando e Abrindo Sessões Completas
++====================================
++
++O Sage é flexível para salvar e abrir sessões completas.
++
++O comando ``save_session(sessionname)`` salva todas as variáveis que
++você definiu na sessão atual como um dicionário com o nome
++``sessionname``. (No caso raro de uma variável não poder ser salva,
++ela simplesmente não aparece no dicionário.) O resultado é um arquivo
++``.sobj`` que pode ser aberto como qualquer outro objeto que foi
++salvado. Quando você abre os objetos que foram salvados em uma sessão,
++você obtém um dicionário cujas chaves (keys) são os nomes das
++variáveis e os valores são os objetos.
++
++Você pode usar o comando ``load_session(sessionname)`` para carregar
++na presente sessão as variáveis definidas em ``sessioname``. Note que
++isso não remove as variáveis já definidas na presente sessão; em vez
++disso, as duas sessões são combinadas.
++
++Primeiro iniciamos o Sage e definimos algumas variáveis.
++
++.. skip
++
++::
++
++    sage: E = EllipticCurve('11a')
++    sage: M = ModularSymbols(37)
++    sage: a = 389
++    sage: t = M.T(2003).matrix(); t.charpoly().factor()
++     _4 = (x - 2004) * (x - 12)^2 * (x + 54)^2
++
++A seguir nós salvamos a nossa sessão, o que armazena cada uma das
++variáveis acima em um arquivo. Então visualizamos o arquivo, que tem
++por volta de 3K bytes.
++
++.. skip
++
++::
++
++    sage: save_session('misc')
++    Saving a
++    Saving M
++    Saving t
++    Saving E
++    sage: quit
++    was at form:~/tmp$ ls -l misc.sobj
++    -rw-r--r--  1 was was 2979 2006-01-28 19:47 misc.sobj
++
++Por fim reiniciamos o Sage, definimos algumas variáveis extra, e
++carregamos a sessão que foi salva anteriormente.
++
++.. skip
++
++::
++
++    sage: b = 19
++    sage: load_session('misc')
++    Loading a
++    Loading M
++    Loading E
++    Loading t
++
++Cada variável que foi salva está de novo disponível. Além disso, a
++variável ``b`` não foi redefinida.
++
++.. skip
++
++::
++
++    sage: M
++    Full Modular Symbols space for Gamma_0(37) of weight 2 with sign 0 
++    and dimension 5 over Rational Field
++    sage: E
++    Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational 
++    Field
++    sage: b
++    19
++    sage: a
++    389
++
++
++
++.. _section-notebook:
++
++A Interface do Notebook
++=======================
++
++O Sage Notebook é iniciado digitando
++
++.. skip
++
++::
++
++    sage: notebook()
++
++na linha de comando do Sage. Isso inicia o Notebook e abre o seu
++browser padrão para visualizá-lo. Os arquivos de estado do servidor
++são armazenados em ``$HOME/.sage/sage\_notebook``.
++
++Outras opções incluem:
++
++.. skip
++
++::
++
++    sage: notebook("directory")
++
++a qual inicia um novo servidor para o Notebook usando arquivos em um
++dado diretório, em vez do diretório padrão
++``$HOME/.sage/sage_notebook``. Isso pode ser útil se você quiser ter
++uma coleção de folhas de trabalho (worksheets) associadas com um
++projeto específico, ou executar vários Notebooks separadamente ao
++mesmo tempo.
++
++Quando você inicia o Notebook, ele primeiro cria os seguintes arquivos
++em ``$HOME/.sage/sage_notebook``:
++
++::
++
++    nb.sobj       (the notebook SAGE object file)
++    objects/      (a directory containing SAGE objects)
++    worksheets/   (a directory containing SAGE worksheets).
++
++Após criar os arquivos acima, o Notebook inicia o servidor web.
++
++Um "Notebook" é uma coleção de contas de usuário, cada qual pode ter
++várias folhas de trabalho (worksheets). Quando você cria uma nova
++folha de trabalho, os dados dela são armazenados no diretórios
++``worksheets/username/number``. Em cada diretório desse há um arquivo
++texto ``worksheet.txt`` - se algum problema ocorrer com as suas
++folhas de trabalho, ou com o Sage, esse arquivo texto contém toda
++informação necessária para reconstruir a folha de trabalho.
++
++A partir do Sage, digite ``notebook?`` para mais informações sobre
++como iniciar um servidor.
++
++O seguinte diagrama ilustra a arquitetura do Notebook Sage:
++
++::
++
++    ----------------------
++    |                    |
++    |                    |
++    |   firefox/safari   |
++    |                    |
++    |     javascript     |
++    |      program       |
++    |                    |
++    |                    |
++    ----------------------
++          |      ^
++          | AJAX |
++          V      |
++    ----------------------
++    |                    |
++    |       sage         |                SAGE process 1
++    |       web          | ------------>  SAGE process 2    (Python processes)
++    |      server        |   pexpect      SAGE process 3
++    |                    |                    .
++    |                    |                    .
++    ----------------------                    .
++
++Para ajuda sobre as teclas de atalho disponíveis no Notebook, clique
++no link ``Help``.
+diff --git a/doc/pt/tutorial/interfaces.rst b/doc/pt/tutorial/interfaces.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/interfaces.rst
+@@ -0,0 +1,341 @@
++.. linkall
++
++**********
++Interfaces
++**********
++
++Uma característica central do Sage é que ele permite fazer cálculos
++com objetos em vários sistemas de álgebra computacional usando uma
++interface comum e uma linguagem de programação clara.
++
++Os métodos console e interact de uma interface executam tarefas bem
++diferentes. Por exemplo, usando GAP:
++
++#. ``gap.console()``: Isso abre um console do GAP - o controle é
++   transferido para o GAP. Aqui o Sage não é nada mais do que uma
++   forma conveniente de executar um programa, similar à shell Bash do
++   Linux.
++
++#. ``gap.interact()``: Essa é uma forma de interagir com uma instância
++   do GAP que pode estar cheia de objetos do Sage. Você pode
++   importar objetos nessa seção do GAP (até mesmo a partir da
++   interface interativa), etc.
++
++
++.. index: PARI; GP
++
++GP/PARI
++=======
++
++O PARI é um programa em C muito compacto, maduro, e extremamente
++otimizado cujo foco primário é teoria de números. Existem duas
++interfaces distintas que podem ser usadas no Sage:
++
++
++-  ``gp`` - o "**G** do **P** ARI" interpretador, e
++
++-  ``pari`` - a biblioteca C do PARI.
++
++Por exemplo, os seguintes comandos são duas formas de realizar a mesma
++coisa. Eles parecem idênticos, mas o resultado é na verdade
++diferente, e o que acontece por trás da cena é bastante diferente.
++
++::
++
++    sage: gp('znprimroot(10007)')
++    Mod(5, 10007)
++    sage: pari('znprimroot(10007)')
++    Mod(5, 10007)
++
++No primeiro caso, uma cópia separada do interpretador GP é iniciada
++como um servidor, e a string ``´znprimroot(10007)'`` é enviada,
++calculada pelo GP, e o resultado é armazenado em uma variável no GP
++(que ocupa espaço na memória dos processos do GP que não serão
++liberados). Então o valor dessa variável é exibido. No segundo caso,
++nenhum programa separado é iniciado, e a string
++``´znprimroot(10007)'`` é calculada por uma certa função da biblioteca
++C do PARI. O resultado é armazenado na memória em uso pelo Python, que
++é liberada quando a variável não for mais referenciada. Os objetos
++possuem tipos diferentes:
++
++::
++
++    sage: type(gp('znprimroot(10007)'))
++    <class 'sage.interfaces.gp.GpElement'>
++    sage: type(pari('znprimroot(10007)'))
++    <type 'sage.libs.pari.gen.gen'>
++
++Então qual eu devo usar? Depende do que você está fazendo. A interface
++GP pode fazer absolutamente tudo o que você poderia fazer na linha de
++comando do GP/PARI, pois está simplesmente executando esse programa.
++Em particular, você pode carregar programas complicados em PARI e
++executá-los. Por outro lado, a interface do PARI (via a biblioteca C)
++é muito mais restritiva. Primeiro, nem todas as funções foram
++implementadas. Segundo, bastante código, por exemplo, envolvendo
++integração numérica, não irá funcionar através da interface PARI.
++Todavia, a interface PARI pode ser significamente mais rápida e mais
++robusta do que a interface GP.
++
++(Se a interface GP ficar sem memória para calcular algum comando, ela
++irá silenciosamente e automaticamente duplicar a memória alocada e
++repetir o comando solicitado. Então os seus cálculos não irão ser
++interrompidos se você não antecipou corretamente a quantidade de
++memória que seria necessária. Esse é um truque útil que a interface
++usual do GP não parece fornecer. Com respeito à interface da
++biblioteca C do PARI, ela imediatamente copia cada objeto criado para
++fora da pilha de memória, logo essa pilha nunca irá crescer. Contudo,
++cada objeto não deve exceder 100MB de tamanho, ou a pilha irá estourar
++quando o objeto for criado. Essa procedimento de cópia impõe uma leve
++pena sobre a performace.)
++
++Em resumo, o Sage usa a biblioteca C do pari para fornecer
++funcionalidade similar à fornecida pelo interpretador GP/PARI, exceto
++que com um gerenciamento sofisticado de memória e a linguagem de
++programação Python.
++
++Primeiro criamos uma lista do PARI a partir de uma lista do Python.
++
++::
++
++    sage: v = pari([1,2,3,4,5])
++    sage: v
++    [1, 2, 3, 4, 5]
++    sage: type(v)
++    <type 'sage.libs.pari.gen.gen'>
++
++Cada objeto do PARI é do tipo ``py_pari_gem``. O tipo PARI do objeto
++subjacente pode ser obtido usando a função ``type``.
++
++::
++
++    sage: v.type()
++    't_VEC'
++
++Em PARI, para criar uma curva elíptica digitamos
++``ellinit([1,2,3,4,5])``. Em Sage é similar, exceto que ``ellnint`` é
++um método que pode ser chamado em qualquer objeto do PARI, por
++exemplo, ``t\_VEC v``.
++
++::
++
++    sage: e = v.ellinit()
++    sage: e.type()         
++    't_VEC'
++    sage: pari(e)[:13]
++    [1, 2, 3, 4, 5, 9, 11, 29, 35, -183, -3429, -10351, 6128487/10351]
++
++Agora que temos um objeto de curva elíptica, podemos calcular algumas
++coisas a respeito dele.
++
++::
++
++    sage: e.elltors()
++    [1, [], []]
++    sage: e.ellglobalred()
++    [10351, [1, -1, 0, -1], 1]
++    sage: f = e.ellchangecurve([1,-1,0,-1])
++    sage: f[:5]
++    [1, -1, 0, 4, 3]
++
++.. index: GAP
++
++.. _section-gap:
++
++GAP
++===
++
++O Sage vem com o GAP 4.4.10 para matemática discreta computacional,
++especialmente teoria de grupos.
++
++Aqui está um exemplo com a função ``IdGroup`` do GAP, a qual usa a
++base de dados opcional sobre grupos que precisa ser instalada
++separadamente, como explicado abaixo.
++
++::
++
++    sage: G = gap('Group((1,2,3)(4,5), (3,4))')
++    sage: G
++    Group( [ (1,2,3)(4,5), (3,4) ] )
++    sage: G.Center()
++    Group( () )
++    sage: G.IdGroup()    # requires optional database_gap package
++    [ 120, 34 ]
++    sage: G.Order()
++    120
++
++Podemos realizar os mesmos cálculos no Sage sem explicitamente evocar
++a interface do GAP da seguinte forma:
++
++::
++
++    sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
++    sage: G.center()
++    Subgroup of (Permutation Group with generators [(3,4), (1,2,3)(4,5)]) generated by [()]
++    sage: G.group_id()     # requires optional database_gap package
++    [120, 34]
++    sage: n = G.order(); n
++    120
++
++(Para alguns recursos adicionais do GAP, você deve instalar dois
++pacotes opcionais. Digite ``sage -optional`` para uma lista e escolha
++o pacote da forma ``gap\_packages-x.y.z``, então digite ``sage -i
++gap\_packages-x.y.z``. Faça o mesmo para ``database\_gap-x.y.z``.
++Alguns pacotes do GAP sem licensa GPL podem ser obtidos no site do GAP
++[GAPkg]_, e copiados em ``$SAGE_ROOT/local/lib/gap-4.4.10/pkg``.)
++
++Singular
++========
++
++O Singular fornece uma biblioteca massiva e madura para bases de
++Gröbner, máximo divisor comum para poliômios em várias variaveis,
++bases de espaços de Riemann-Roch de uma curva plana, e fatorização,
++entre outras coisas. Vamos ilustrar a fatorização de polinômios em
++várias variáveis usando a interface do Sage para o Singular (não
++digite ``...``):
++
++::
++
++    sage: R1 = singular.ring(0, '(x,y)', 'dp')
++    sage: R1
++    //   characteristic : 0
++    //   number of vars : 2
++    //        block   1 : ordering dp
++    //                  : names    x y 
++    //        block   2 : ordering C
++    sage: f = singular('9*y^8 - 9*x^2*y^7 - 18*x^3*y^6 - 18*x^5*y^6 + \
++    ...   9*x^6*y^4 + 18*x^7*y^5 + 36*x^8*y^4 + 9*x^10*y^4 - 18*x^11*y^2 - \
++    ...   9*x^12*y^3 - 18*x^13*y^2 + 9*x^16')
++
++Agora que definimos :math:`f`, vamos imprimi-lo e fatorá-lo.
++
++::
++
++    sage: f
++    9*x^16-18*x^13*y^2-9*x^12*y^3+9*x^10*y^4-18*x^11*y^2+36*x^8*y^4+18*x^7*y^5-18*x^5*y^6+9*x^6*y^4-18*x^3*y^6-9*x^2*y^7+9*y^8
++    sage: f.parent()
++    Singular
++    sage: F = f.factorize(); F
++    [1]:
++       _[1]=9
++       _[2]=x^6-2*x^3*y^2-x^2*y^3+y^4
++       _[3]=-x^5+y^2
++    [2]:
++       1,1,2
++    sage: F[1][2]
++    x^6-2*x^3*y^2-x^2*y^3+y^4
++
++Como com o exemplo para o GAP em :ref:`section-gap`, podemos calcular
++a fatorização acima sem explicitamente usar a inteface do Singular
++(todavia, implicitamente o Sage usa a interface do Singular para os
++cálculos). Não digite ``...``:
++
++::
++
++    sage: x, y = QQ['x, y'].gens()
++    sage: f = 9*y^8 - 9*x^2*y^7 - 18*x^3*y^6 - 18*x^5*y^6 + 9*x^6*y^4\
++    ...   + 18*x^7*y^5 + 36*x^8*y^4 + 9*x^10*y^4 - 18*x^11*y^2 - 9*x^12*y^3\
++    ...   - 18*x^13*y^2 + 9*x^16
++    sage: factor(f)
++    (9) * (-x^5 + y^2)^2 * (x^6 - 2*x^3*y^2 - x^2*y^3 + y^4)
++
++.. _section-maxima:
++
++Maxima
++======
++
++O Maxima está incluido no Sage, assim como uma implementação do Lisp.
++O pacote gnuplot (que o Maxima usa para criar gráficos) é distribuído
++como um pacote adicional do Sage. Entre outras coisas, o Maxima
++executa manipulações simbólicas. Ele pode integrar e diferenciar
++funções simbolicamente, resolver EDOs de primeira ordem, grande parte
++das EDOs lineares de segunda ordem, e tem implementado o método da
++transformada de Laplace para EDOs lineares de qualquer ordem. O Maxima
++também suporta uma série de funções especiais, é capaz de criar
++gráficos via gnuplot, e possui métodos para resolver equações
++polinômiais e manipular matrizes (por exemplo, escalonar e calcular
++autovalores e autovetores).
++
++Nós ilustramos a interface Sage/Maxima construíndo uma matriz cuja
++entrada :math:`i,j` é :math:`i/j`, para :math:`i,j=1,\ldots,4`.
++
++::
++
++    sage: f = maxima.eval('ij_entry[i,j] := i/j')
++    sage: A = maxima('genmatrix(ij_entry,4,4)'); A
++    matrix([1,1/2,1/3,1/4],[2,1,2/3,1/2],[3,3/2,1,3/4],[4,2,4/3,1])
++    sage: A.determinant()
++    0
++    sage: A.echelon()
++    matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0])
++    sage: A.eigenvalues()
++    [[0,4],[3,1]]
++    sage: A.eigenvectors()
++    [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]]
++
++Aqui vai outro exemplo:
++
++::
++
++    sage: A = maxima("matrix ([1, 0, 0], [1, -1, 0], [1, 3, -2])")
++    sage: eigA = A.eigenvectors()
++    sage: V = VectorSpace(QQ,3)
++    sage: eigA
++    [[[-2,-1,1],[1,1,1]],[[[0,0,1]],[[0,1,3]],[[1,1/2,5/6]]]]
++    sage: v1 = V(sage_eval(repr(eigA[1][0][0]))); lambda1 = eigA[0][0][0]
++    sage: v2 = V(sage_eval(repr(eigA[1][1][0]))); lambda2 = eigA[0][0][1]
++    sage: v3 = V(sage_eval(repr(eigA[1][2][0]))); lambda3 = eigA[0][0][2]
++    
++    sage: M = MatrixSpace(QQ,3,3)
++    sage: AA = M([[1,0,0],[1, - 1,0],[1,3, - 2]])
++    sage: b1 = v1.base_ring()
++    sage: AA*v1 == b1(lambda1)*v1
++    True
++    sage: b2 = v2.base_ring()
++    sage: AA*v2 == b2(lambda2)*v2
++    True
++    sage: b3 = v3.base_ring()
++    sage: AA*v3 == b3(lambda3)*v3
++    True
++
++Por fim, apresentamos um exemplo de como usar o Sage para criar
++gráficos usando ``openmath``. Alguns desses exemplos são modificações
++de exemplos do manual de referência do Maxima.
++
++Um gráfico em duas dimensões de diversas funções (não digite ``...``):
++
++::
++
++    sage: maxima.plot2d('[cos(7*x),cos(23*x)^4,sin(13*x)^3]','[x,0,1]',\
++    ...   '[plot_format,openmath]') # not tested
++
++Um gráfico em 3D que você pode mover com o seu mouse:
++
++::
++
++    sage: maxima.plot3d ("2^(-u^2 + v^2)", "[u, -3, 3]", "[v, -2, 2]",\
++    ...   '[plot_format, openmath]') # not tested
++    sage: maxima.plot3d("atan(-x^2 + y^3/4)", "[x, -4, 4]", "[y, -4, 4]",\
++    ...   "[grid, 50, 50]",'[plot_format, openmath]') # not tested
++
++O próximo gráfico é a famosa faixa de Möbious:
++
++::
++
++    sage: maxima.plot3d("[cos(x)*(3 + y*cos(x/2)), sin(x)*(3 + y*cos(x/2)),\
++    ...   y*sin(x/2)]", "[x, -4, 4]", "[y, -4, 4]",\ 
++    ...   '[plot_format, openmath]') # not tested
++
++E agora a famosa garrafa de Klein:
++
++::
++
++    sage: maxima("expr_1: 5*cos(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)\
++    ...   - 10.0")
++    5*cos(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)-10.0
++    sage: maxima("expr_2: -5*sin(x)*(cos(x/2)*cos(y) + sin(x/2)*sin(2*y)+ 3.0)")
++    -5*sin(x)*(sin(x/2)*sin(2*y)+cos(x/2)*cos(y)+3.0)
++    sage: maxima("expr_3: 5*(-sin(x/2)*cos(y) + cos(x/2)*sin(2*y))")
++    5*(cos(x/2)*sin(2*y)-sin(x/2)*cos(y))
++    sage: maxima.plot3d ("[expr_1, expr_2, expr_3]", "[x, -%pi, %pi]",\
++    ...   "[y, -%pi, %pi]", "['grid, 40, 40]",\
++    ...   '[plot_format, openmath]') # not tested
+diff --git a/doc/pt/tutorial/introduction.rst b/doc/pt/tutorial/introduction.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/introduction.rst
+@@ -0,0 +1,165 @@
++**********
++Introdução
++**********
++
++Este tutorial leva no máximo de 3 a 4 horas para ser percorrido. Você
++pode lê-lo em versão HTML ou PDF, ou a partir do Notebook Sage (clique
++em ``Help``, então clique em ``Tutorial`` para percorrer o tutorial de
++forma interativa).
++
++Embora grande parte do Sage seja implementado em Python, nenhum
++conhecimento de Python é necessário para a leitura deste tutorial.
++Você vai querer aprender Python (uma linguagem muito divertida!) em
++algum momento, e existem diversas opções gratuitas disponíveis para
++isso, entre elas [PyT]_ e [Dive]_ (em inglês). Se você quiser
++experimentar o Sage rapidamente, este tutorial é o lugar certo para
++começar. Por exemplo:
++
++::
++
++    sage: 2 + 2
++    4
++    sage: factor(-2007)
++    -1 * 3^2 * 223
++
++    sage: A = matrix(4,4, range(16)); A
++    [ 0  1  2  3]
++    [ 4  5  6  7]
++    [ 8  9 10 11]
++    [12 13 14 15]
++
++    sage: factor(A.charpoly())
++    x^2 * (x^2 - 30*x - 80)
++
++    sage: m = matrix(ZZ,2, range(4))
++    sage: m[0,0] = m[0,0] - 3
++    sage: m
++    [-3  1]
++    [ 2  3]
++
++    sage: E = EllipticCurve([1,2,3,4,5]);
++    sage: E
++    Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5
++    over Rational Field
++    sage: E.anlist(10)
++    [0, 1, 1, 0, -1, -3, 0, -1, -3, -3, -3]
++    sage: E.rank()
++    1
++
++    sage: k = 1/(sqrt(3)*I + 3/4 + sqrt(73)*5/9); k
++    1/(I*sqrt(3) + 5/9*sqrt(73) + 3/4)
++    sage: N(k)
++    0.165495678130644 - 0.0521492082074256*I
++    sage: N(k,30)      # 30 "bits"
++    0.16549568 - 0.052149208*I
++    sage: latex(k)
++    \frac{1}{i \, \sqrt{3} + \frac{5}{9} \, \sqrt{73} + \frac{3}{4}}
++
++.. _installation:
++
++Instalação
++==========
++
++Se você não tem o Sage instalado em um computador e quer apenas
++experimentar alguns comandos, use o Sage através do site
++http://www.sagenb.org.
++
++Veja o guia de instalação do Sage na seção de documentação na página
++principal do Sage [SA]_ para instruções de como instalar o Sage no seu
++computador. Aqui faremos apenas alguns comentários.
++
++#. O arquivo para download do Sage vem com "baterias incluídas". Em
++   outras palavras, embora o Sage use o Python, IPython, PARI, GAP,
++   Singular, Maxima, NTL, GMP, e uma série de outros programas, você
++   não precisa instalá-los separadamente pois eles estão incluídos no
++   Sage. Todavia, para usar alguns recursos, por exemplo, o Macaulay
++   ou o KASH, você precisa instalar pacotes de software adicionais ou
++   ter os programas necessários já instalados no seu computador. O
++   Macaulay e o KASH estão disponíveis como pacotes adicionais do Sage
++   (para uma lista de pacotes adicionais, digite ``sage -optional``,
++   ou visite a seção "Download" na página do Sage na internet).
++
++#. A versão pré-compilada do Sage (disponível na página do Sage na
++   internet) pode ser mais fácil e rápida para instalar do que a
++   versão obtida compilando o código fonte.
++
++#. Se você quiser usar o pacote SageTeX (que permite inserir
++   cálculos do Sage em um arquivo LaTeX), você deve tornar
++   o SageTex disponível para a sua distribuição TeX. Para fazer isso,
++   consulte a seção "Make SageTex known to TeX" no `Sage installation
++   guide <http://www.sagemath.org/doc/>`_. O procedimento é bem
++   simples; você precisa apenas definir algumas variáveis no seu
++   sistema ou copiar um arquivo para um diretório onde o TeX poderá
++   encontrá-lo.
++
++   A documentação para usar o SageTex está disponível em
++   ``$SAGE_ROOT/local/share/texmf/tex/generic/sagetex/``, onde
++   ``$SAGE_ROOT`` refere-se ao diretório onde você instalou o Sage
++   -- por exemplo, ``/opt/sage-4.2.1``.
++
++Formas de usar o Sage
++=====================
++
++Você pode usar o Sage de diversas formas.
++
++
++-  **Interface gráfica Notebook:** veja a seção sobre o Notebook em
++   :ref:`section-notebook`,
++
++-  **Linha de comando interativa:** veja
++   :ref:`chapter-interactive_shell`,
++
++-  **Programas:** escrevendo programas interpretados e compilados em
++   Sage (veja :ref:`section-loadattach` e :ref:`section-compile`), e
++
++-  **Scripts:** escrevendo scripts em Python que usam a biblioteca do
++   Sage (veja :ref:`section-standalone`).
++
++
++Objetivos do Sage a longo prazo
++===============================
++
++-  **Útil**: O público alvo do Sage são estudantes de matemática
++   (desde o ensino médio até a pós-graduação), professores, e
++   pesquisadores em matemática. O objetivo é fornecer um software que
++   possa ser usado para explorar e experimentar construções matemáticas
++   em álgebra, geometria, teoria de números, cálculo, computação
++   numérica, etc. O Sage torna mais fácil a experimentação com objetos
++   matemáticos de forma interativa.
++
++-  **Eficiente:** Ser rápido. O Sage usa software bastante otimizado
++   como o GMP, PARI, GAP, e NTL, e portanto é muito rápido em certas
++   operações.
++
++-  **Gratuito e de código aberto:** O código fonte deve ser amplamente
++   disponível e legível, de modo que os usuários possam entender o que
++   o software realmente faz e possam facilmente estendê-lo. Da mesma
++   forma que matemáticos ganham entendimento sobre um teorema lendo
++   cuidadosamente a sua demonstração, as pessoas que fazem cálculos
++   deveriam poder entender como os cálculos são feitos lendo o código
++   fonte e seus comentários. Se você usar o Sage para fazer cálculos em
++   um artigo que seja publicado, você pode ter certeza que os leitores
++   sempre terão livre acesso ao Sage e seu código fonte, e você tem até
++   mesmo permissão para arquivar e redistribuir a versão do Sage que
++   você utilizou.
++
++-  **Fácil de compilar:** O Sage deve ser fácil de compilar a partir
++   do código fonte para usuários de Linux, OS X e Windows. Isso
++   fornece mais flexibilidade para os usuários modificarem o sistema.
++
++-  **Cooperação:** Fornecer uma interface robusta para outros sistemas
++   computacionais, incluindo PARI, GAP, Singular, Maxima, KASH, Magma,
++   Maple e Mathematica. O Sage foi concebido para unificar e estender
++   outros softwares de matemática existentes.
++
++-  **Bem documentado:** Tutorial, guia de programação, manual de
++   referência, e how-to, com inúmeros exemplos e discussão sobre
++   conceitos matemáticos relacionados.
++
++-  **Estensível:** Ser capaz de definir novos tipos de dados ou
++   derivá-los a partir dos tipos de dados existentes, e usar programas
++   escritos em diversas outras linguagens.
++
++-  **Fácil de usar:** Deve ser fácil entender quais recursos estão
++   disponíveis para um determinado objeto e consultar a documentação e
++   o código fonte.
+diff --git a/doc/pt/tutorial/latex.rst b/doc/pt/tutorial/latex.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/latex.rst
+@@ -0,0 +1,515 @@
++*********************************
++Sage, LaTeX e Companheiros
++*********************************
++
++AUTOR:  Rob Beezer (2010-05-23)
++
++O Sage e o dialeto LaTeX do TeX tem um relacionamento sinergético
++intenso. Esta seção tem como objetivo introduzir as diversas formas de
++interação entre eles, começado pelas mais básicas e indo até as menos
++usuais. (Logo você pode não querer ler esta seção inteira na sua
++primeira passagem por este tutorial.)
++
++Panorama Geral
++==============
++
++Pode ser mais fácil entender os vários usos do LaTeX com um panorama
++geral sobre os três principais métodos usados pelo Sage.
++
++#. Todo objeto no Sage possui uma representação em LaTeX. Você
++   pode acessar essa representação executando, no Notebook ou na
++   linha de comando do Sage, ``latex(foo)`` where ``foo`` é algum
++   objeto no Sage. O resultado é uma string que deve fornecer uma
++   representação razoável de ``foo`` no modo matemático em LaTeX
++   (por exemplo, quando cercado por um par de símbolos $). Alguns
++   exemplos disso seguem abaixo.
++
++   Dessa forma, o Sage pode ser usado efetivamente para construir
++   partes de um documento LaTeX: crie ou calcule um objeto no
++   Sage, imprima ``latex()`` do objeto e copie-e-cole o resultado
++   no seu documento.
++
++#. A interface Notebook é configurada para usar o `jsMath
++   <http://www.math.union.edu/~dpvc/jsMath/>`_ para representar
++   fórmulas matemáticas de forma clara em um web browser. O jsMath é
++   uma coleção de rotinas em JavaScript e fontes associadas.
++   Tipicamente esses fontes ficam armazenadas em um servidor e são
++   enviadas para o browser juntamente com a página onde elas estão
++   sendo usadas. No caso do Sage, o Notebook está sempre conectado a
++   um servidor usado para executar os comando do Sage, e esse servidor
++   também fornece as fontes do jsMath necessárias. Logo não é
++   necessário configurar nada mais para ter formulas matemáticas
++   representadas no seu browser quando você usa o Notebook do Sage.
++
++   O jsMath é implementado para representar um subconjunto grande,
++   mas não completo, do TeX. Ele não suporta objetos como, por
++   exemplo, tabelas complicadas e seções, e é focado para
++   representar acuradamente pequenas fórmulas em TeX. A
++   representação automática de fórmulas matemáticas no Notebook é
++   obtida convertendo a representação ``latex()`` de um objeto
++   (como descrito acima) em uma forma de HTML mais adequada ao
++   jsMath.
++
++   Como o jsMath usa as suas próprias fontes de tamanho variável,
++   ele é superior a outros métodos que convertem equações, ou
++   outros pequenos trechos de TeX, em imagens estáticas.
++
++   O jsMath muito provavelmente vai ser substituído pelo MathJAX,
++   uma tecnologia similar do mesmo autor, que possui suporte
++   extenso de editoras técnicas e sociedades profissionais.
++
++#. Na linha de comando do Sage, ou no Notebook quando o código em
++   LaTeX é complicado demais para o jsMath processar, uma
++   instalação local do LaTeX pode ser usada. O Sage inclui quase
++   tudo que você precisa para compilar e usar o Sage, mas uma
++   exceção significativa é o TeX. Então nessas situações você
++   precisa ter o TeX instalado, juntamente com algumas ferramentas
++   de conversão, para usar os recursos completos.
++
++Aqui nós demonstramos alguns usos básicos da função ``latex()``. ::
++
++    sage: var('z')
++    z
++    sage: latex(z^12)
++    z^{12}
++    sage: latex(integrate(z^4, z))
++    \frac{1}{5} \, z^{5}
++    sage: latex('a string')
++    \verb|a|\phantom{x}\verb|string|
++    sage: latex(QQ)
++    \Bold{Q}
++    sage: latex(matrix(QQ, 2, 3, [[2,4,6],[-1,-1,-1]]))
++    \left(\begin{array}{rrr}
++    2 & 4 & 6 \\
++    -1 & -1 & -1
++    \end{array}\right)
++
++A funcionalidade básica do jsMath é em sua maior parte automática no
++Notebook, mas nós podemos demonstrar esse suporte parcialmente com a
++classe ``jsMath``. A função ``eval`` dessa classe converte um objeto
++do Sage em sua representação LaTeX e adiciona HTML que por sua vez
++evoca a classe "matemática" do CSS, a qual então emprega o jsMath. ::
++
++    sage: from sage.misc.latex import JSMath
++    sage: js = JSMath()
++    sage: var('z')
++    z
++    sage: js(z^12)
++    <html><div class="math">\newcommand{\Bold}[1]{\mathbf{#1}}z^{12}</div></html>
++    sage: js(QQ)
++    <html><div class="math">\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}</div></html>
++    sage: js(ZZ[x])
++    <html><div class="math">\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Z}[x]</div></html>
++    sage: js(integrate(z^4, z))
++    <html><div class="math">\newcommand{\Bold}[1]{\mathbf{#1}}\frac{1}{5} \, z^{5}</div></html>
++
++Uso Básico
++==========
++
++Como indicado acima, a forma mais simples de explorar o suporte do
++Sage para o LaTeX é usando a função ``latex()`` para criar código
++LaTeX para representar objetos matemáticos. Essas strings podem então
++ser incorporadas em documentos LaTeX. Isso funciona igualmente no
++Notebook ou na linha de comando do Sage.
++
++No outro extremo está o comando ``view()``. Na linha de comando do
++Sage o comando ``view(foo)`` irá criar a representação em LaTeX de
++``foo``, incorporar isso em um documento simples em LaTeX, e então
++processar o documento usando o LaTeX em seu sistema. Por fim, o
++visualizador apropriado será aberto para apresentar o documento
++gerado. Qual versão do TeX é usada, e portanto as opções para a saída
++e visualizador, podem ser personalizados (veja
++:ref:`sec-custom-processing`).
++
++No Notebook, o comando ``view(foo)`` cria uma combinação apropriada de
++HTML e CSS para que o jsMath mostre a representação em LaTeX na folha
++de trabalho. Para o usuário, ele simplesmente cria uma versão
++cuidadosamente formatada do resultado, distinta da saída padrão em
++modo texto do Sage. Nem todo objeto no Sage possui uma representação
++em LaTeX adequada às capacidades limitadas do jsMath. Nesses casos, a
++interpretação pelo jsMath pode ser deixada de lado, e com isso o LaTeX
++do sistema é chamado, e o resultado dessa chamada é convertido em uma
++imagem que é inserida na folha de trabalho. Como alterar e controlar
++esse processo é discutido abaixo na seção
++:ref:`sec-custom-generation`.
++
++O comando interno ``pretty_print()`` ilustra a conversão de objetos do
++Sage para HTML que emprega o jsMath no Notebook. ::
++
++    sage: from sage.misc.latex import pretty_print
++    sage: pretty_print(x^12)
++    <html><span class="math">\newcommand{\Bold}[1]{\mathbf{#1}}x^{12}</span></html>
++    sage: pretty_print(integrate(sin(x), x))
++    <html><span class="math">\newcommand{\Bold}[1]{\mathbf{#1}}-\cos\left(x\right)</span></html>
++
++O Notebook tem outros dois recursos para empregar o TeX. O primeiro é
++o botão "Typeset" bem acima da primeira célula da folha de trabalho, à
++direita dos quatro menus de opções. Quando selecionado, o resultado de
++qualquer cálculo vai ser interpretado pelo jsMath. Note que esse
++efeito não é retroativo -- células calculadas anteriormente precisam
++ser recalculadas para ter o resultado representado pelo jsMath.
++Essencialmente, selecionar o botão "Typeset" é equivalente a aplicar o
++comando ``view()`` ao resultado de cada célula.
++
++Um segundo recurso disponível no Notebook é possibilidade de inserir
++código TeX para fazer anotações na folha de trabalho. Quando o cursos
++esta posicionado entre células de modo que uma barra azul fica
++visível, então shift-click irá abrir um mini processador de texto,
++TinyMCE. Isso permite digitar texto, usando um editor WSISYG para
++criar HTML e CSS. Logo é possível inserir texto formatado para
++complementar a folha de trabalho. Todavia, texto entre símbolos $, ou
++$$, é interpretado pelo jsMath como "inline" ou "display math"
++espectivamente.
++
++.. _sec-custom-generation:
++
++Personalizando a Criação de Código LaTeX
++========================================
++
++Exitem várias formas de personalizar o código LaTeX gerado pelo
++comando ``latex()``. No Notebook e na linha de comando existe um
++objeto pré-definido chamado ``latex`` que possui diversos métodos, os
++quais você pode listar digitando ``latex.``, seguido da tecla tab
++(note a presença do ponto).
++
++Um bom exemplo é o método ``latex.matrix_delimiters``. Ele pode ser
++usado para alterar a notação de matrizes -- parênteses grandes,
++colchetes, barras verticais. Nenhuma noção de estilo é enfatizada,
++você pode configurar como desejado. Observe como as barras invertidas
++usadas em LaTeX requerem uma barra adicional de modo que elas possam
++ser interpretadas (escaped) corretamente em uma string do Python. ::
++
++    sage: A = matrix(ZZ, 2, 2, range(4))
++    sage: latex(A)
++    \left(\begin{array}{rr}
++    0 & 1 \\
++    2 & 3
++    \end{array}\right)
++    sage: latex.matrix_delimiters(left='[', right=']')
++    sage: latex(A)
++    \left[\begin{array}{rr}
++    0 & 1 \\
++    2 & 3
++    \end{array}\right]
++    sage: latex.matrix_delimiters(left='\\{', right='\\}')
++    sage: latex(A)
++    \left\{\begin{array}{rr}
++    0 & 1 \\
++    2 & 3
++    \end{array}\right\}
++
++O método ``latex.vector_delimiters`` funciona de forma similar.
++
++A forma como anéis e corpos comuns podem ser representados pode ser
++controlada pelo método ``latex.blackboard_bold``. Esses conjuntos são
++representados por padrão em negrito, mas podem opcionalmente ser
++escritos em letras duplas como é comum em trabalhos escritos. Isso é
++obtido redefinindo a macro ``\Bold{}`` que faz parte do Sage. ::
++
++    sage: latex(QQ)
++    \Bold{Q}
++    sage: from sage.misc.latex import JSMath
++    sage: js=JSMath()
++    sage: js(QQ)
++    <html><div class="math">\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}</div></html>
++    sage: latex.blackboard_bold(True)
++    sage: js(QQ)
++    <html><div class="math">\newcommand{\Bold}[1]{\mathbb{#1}}\Bold{Q}</div></html>
++    sage: latex.blackboard_bold(False)
++
++É possível aproveitar os recursos do TeX adicionando novas macros e
++novos pacotes. Primeiro, macros individuais podem ser adicionadas para
++serem usadas quando o jsMath interpreta pequenos trechos de códigos
++TeX no Notebook. ::
++
++    sage: latex.extra_macros()
++    ''
++    sage: latex.add_macro("\\newcommand{\\foo}{bar}")
++    sage: latex.extra_macros()
++    '\\newcommand{\\foo}{bar}'
++    sage: var('x y')
++    (x, y)
++    sage: latex(x+y)
++    x + y
++    sage: from sage.misc.latex import JSMath
++    sage: js=JSMath()
++    sage: js(x+y)
++    <html><div class="math">\newcommand{\Bold}[1]{\mathbf{#1}}\newcommand{\foo}{bar}x + y</div></html>
++
++Macros adicionais usadas dessa forma serão também usadas eventualmente
++se a versão do TeX no seu sistema for usada para lidar com algo muito
++complicado para o jsMath. O comando ``latex_extra_preamble`` é usado
++para construir o preambulo de um documento completo em LaTeX.
++Ilustramos a seguir como fazer isso. Novamente note a necessidade de
++barras invertidas duplas nas strings do Python. ::
++
++
++    sage: latex.extra_macros('')
++    sage: latex.extra_preamble('')
++    sage: from sage.misc.latex import latex_extra_preamble
++    sage: print latex_extra_preamble()
++    \newcommand{\ZZ}{\Bold{Z}}
++    ...
++    \newcommand{\Bold}[1]{\mathbf{#1}}
++    sage: latex.add_macro("\\newcommand{\\foo}{bar}")
++    sage: print latex_extra_preamble()
++    \newcommand{\ZZ}{\Bold{Z}}
++    ...
++    \newcommand{\Bold}[1]{\mathbf{#1}}
++    \newcommand{\foo}{bar}
++
++Novamente, para expressões grandes ou mais complicadas do LaTeX, é
++possível adicionar pacotes (ou qualquer outra coisa) ao preambulo do
++arquivo LaTeX. Qualquer coisa pode ser incorporada no preambulo com o
++comando ``latex.add_to_preamble``, e o comando mais especializado
++``latex.add_package_to_preamble_if_available`` irá primeiro verificar
++se certo pacote está realmente disponível antes de adicioná-lo ao
++preambulo
++
++Agora adicionamos o pacote geometry ao preambulo e usamos ele para
++definir o tamanho da região na página que o TeX vai usar
++(efetivamente definido as margens). Novamente, observe a necessidade
++de barras duplas nas strings do Python. ::
++
++
++    sage: from sage.misc.latex import latex_extra_preamble
++    sage: latex.extra_macros('')
++    sage: latex.extra_preamble('')
++    sage: latex.add_to_preamble('\\usepackage{geometry}')
++    sage: latex.add_to_preamble('\\geometry{letterpaper,total={8in,10in}}')
++    sage: latex.extra_preamble()
++    '\\usepackage{geometry}\\geometry{letterpaper,total={8in,10in}}'
++    sage: print latex_extra_preamble()
++    \usepackage{geometry}\geometry{letterpaper,total={8in,10in}}
++    \newcommand{\ZZ}{\Bold{Z}}
++    ...
++    \newcommand{\Bold}[1]{\mathbf{#1}}
++
++Um pacote pode ser adicionado juntamente com a verificação de sua
++existência, da seguinte forma. Como um exemplo, nós ilustramos uma
++tentativa de adicionar ao preambulo um pacote que supostamente não
++existe. ::
++
++    sage: latex.extra_preamble('')
++    sage: latex.extra_preamble()
++    ''
++    sage: latex.add_to_preamble('\\usepackage{foo-bar-unchecked}')
++    sage: latex.extra_preamble()
++    '\\usepackage{foo-bar-unchecked}'
++    sage: latex.add_package_to_preamble_if_available('foo-bar-checked')
++    sage: latex.extra_preamble()
++    '\\usepackage{foo-bar-unchecked}'
++
++.. _sec-custom-processing:
++
++Personalizando o Processamento em LaTeX
++=======================================
++
++É também possível controlar qual variação do TeX é usada quando a
++versão do sistema for evocada, logo influenciando também o resultado.
++De forma similar, é também possível controlar quando o Notebook irá
++usar o jsMath (trechos simples em TeX) ou a versão do TeX do sistema
++(expressões mais complicadas).
++
++O comando ``latex.engine()`` pode ser usado para controlar de os
++executáveis ``latex``, ``pdflatex`` ou ``xelatex`` do sistema são
++usados para processar expressões mais complicadas. Quando ``view()`` é
++chamado na linha de comando do Sage e o processador é definido como
++``latex``, um arquivo dvi é produzido e o Sage vai usar um
++visualizador de dvi (como o xdvi) para apresentar o resultado. Por
++outro lado, usando ``view()`` na linha de comando do Sage, quando o
++processador é definido como ``pdflatex``, irá produzir um PDF e o Sage vai
++executar o programa disponível no seu sistema para visualizar arquivos
++PDF (acrobat, okular, evince, etc.).
++
++No Notebook, é necessário interver na decisão de se o jsMath vai
++interpretar trechos em TeX, ou se o LaTeX do sistema deve fazer o
++trabalho se o código em LaTeX for complicado demais. O dispositivo é
++uma lista de strings, que se forem encontradas em um trecho de código
++LaTeX sinalizam para o Notebook usar o LaTeX (ou qualquer executável
++que for definido pelo comando ``latex.engine()``). Essa lista é
++gerenciada pelos comandos ``latex.add_to_jsmath_avoid_list`` e
++``latex.jsmath_avoid_list``. ::
++
++    sage: latex.jsmath_avoid_list([])
++    sage: latex.jsmath_avoid_list()
++    []
++    sage: latex.jsmath_avoid_list(['foo', 'bar'])
++    sage: latex.jsmath_avoid_list()
++    ['foo', 'bar']
++    sage: latex.add_to_jsmath_avoid_list('tikzpicture')
++    sage: latex.jsmath_avoid_list()
++    ['foo', 'bar', 'tikzpicture']
++    sage: latex.jsmath_avoid_list([])
++    sage: latex.jsmath_avoid_list()
++    []
++
++Suponha que uma expressão em LaTeX é produzida no Notebook com o
++comando ``view()`` ou enquanto o botão "Typeset" está selecionado, e
++então reconhecida, através da "lista de comandos a serem evitados no
++jsMath", como necessitando a versão do LaTeX no sistema. Então o
++executável selecionado (como especificado por ``latex.engine()``) irá
++processar o código em LaTeX. Todavia, em vez de então abrir um
++visualizador externo (o que é o comportamento na linha de comando), o
++Sage irá tentar converter o resultado em uma imagem, que então é
++inserida na folha de trabalho como o resultado da célula.
++
++Exatamente como essa conversão é feita depende de vários fatores --
++qual executável você especificou como processador e quais utilitários
++de conversão estão disponíveis no seu sistema. Quatro conversores
++usuais que irão cobrir todas as ocorrências são o ``dvips``,
++``ps2pdf``, e ``dvipng``, e do pacote ``ImageMagick``, o ``convert``.
++O objetivo é produzir um arquivo PNG para ser inserido de volta na
++folha de trabalho. Quando uma expressão em LaTeX pode ser convertida
++com sucesso em um arquivo dvi pelo processador LaTeX, então o dvipng
++deve dar conta da conversão. Se a expressão em LaTeX e o processador
++especificado criarem um arquivo dvi com conteúdo especial que o dvipng
++não pode converter, então o dvips vai criar um arquivo PostScript.
++Esse arquivo PostScript, ou um PDF criado por pelo processador
++``pdflatex``, é então convertido em um arquivo dvi pelo programa
++``convert``. A presença de dois desses conversores pode ser testado
++com as rotinas ``have_dvipng()`` e ``have_convert()``.
++
++Essas conversões são feitas automaticamente se você tiver os
++conversores necessários instalados; se não, então uma mensagem de erro
++é impressa dizendo o que está faltando e onde obter.
++
++Para um exemplo concreto de como expressões complicadas em LaTeX podem
++ser processadas, veja o exemplo na próxima seção
++(:ref:`sec-tkz-graph`) para usar o pacote ``tkz-graph`` para produzir
++ilustrações de grafos combinatoriais de alta qualidade. Para outros
++exemplos, existem alguns casos teste incluídos no Sage. Para usá-los,
++é necessário importar o objeto ``sage.misc.latex.latex_examples``, que
++é uma instância da classe ``sage.misc.latex.LatexExamples``, como
++mostrado abaixo. Essa classe possui exemplos de diagramas comutativos,
++grafos combinatoriais, teoria de nós e pstricks, os quais
++respectivamente testam os seguintes pacotes: xy, tkz-graph, xypic,
++pstricks. Após importar o objeto, use completamento tab em
++``latex_examples`` para ver os exemplos disponíveis. Ao carregar um
++exemplo você irá obter explicações sobre o que é necessário para fazer
++o conteúdo do exemplo ser exibido corretamente. Para de fato ver os
++exemplos, é necessário usar ``view()`` (uma vez que o preambulo,
++processador, etc. estão configurados corretamente).
++
++::
++
++    sage: from sage.misc.latex import latex_examples
++    sage: latex_examples.diagram()
++    LaTeX example for testing display of a commutative diagram produced
++    by xypic.
++    <BLANKLINE>
++    To use, try to view this object -- it won't work.  Now try
++    'latex.add_to_preamble("\\usepackage[matrix,arrow,curve,cmtip]{xy}")',
++    and try viewing again -- it should work in the command line but not
++    from the notebook.  In the notebook, run
++    'latex.add_to_jsmath_avoid_list("xymatrix")' and try again -- you
++    should get a picture (a part of the diagram arising from a filtered
++    chain complex).
++
++.. _sec-tkz-graph:
++
++Exemplo: Grafos Combinatoriais com tkz-graph
++============================================
++
++Ilustrações de alta qualidade de grafos combinatoriais (daqui por
++diante, simplesmente grafos) são possíveis com o pacote ``tkz-graph``.
++Esse pacote baseia-se no ``tikz`` front-end da biblioteca ``pgf``.
++Logo todos esses componentes precisam ser parte de uma instalação
++completa do LaTeX em seu sistema, e pode acontecer que alguns desses
++componentes não estejam em sua versão mais recente em algumas
++distribuições do TeX. Logo, para melhores resultados, seria necessário
++ou recomendável instalar esses pacotes como parte do seu diretório
++texmf pessoal. Criar, manter e personalizar uma instalação do TeX no
++sistema ou em um diretório pessoal vai além do escopo deste documento,
++mas deve ser fácil encontrar instruções para isso. Os arquivos
++necessários estão listados em :ref:`sec-system-wide-tex`.
++
++Portanto, para começar precisamos nos certificar que os pacotes
++relevantes estão incluídos adicionando-os ao preambulo do eventual
++documento LaTeX. As imagens dos grafos não são formadas corretamente
++quando um arquivo dvi é usando como formato intermediário, logo é
++melhor definir o processador do LaTeX como ``pdflatex``. A esta altura
++um comando como ``view(graphs.CompleteGraph(4))`` deve funcionar na
++linha de comando do Sage e produzir um PDF com a imagem completa do
++grafo `K_4`.
++
++Para uma experiência semelhante no Notebook, é necessário desabilitar
++o processador jsMath para o código LaTeX do grafo usando a "lista de
++comandos a serem evitados pelo jsMath". Grafos são criados usando o
++environment ``tikzpicture``, logo essa uma boa escolha para uma string
++a ser incluída na lista que acabamos de mencionar. Agora,
++``view(graphs.CompleteGraph(4))`` em uma folha de trabalho deve
++executar o pdflatex para criar um PDF e então o programa ``convert``
++para obter um gráfico PNG que vai ser inserido na folha de trabalho.
++Os seguintes comandos ilustram os passos para obter grafos processados
++pelo LaTeX no Notebook. ::
++
++    sage: from sage.graphs.graph_latex import setup_latex_preamble
++    sage: setup_latex_preamble()
++    sage: latex.extra_preamble() # random - depends on system's TeX installation
++    '\\usepackage{tikz}\n\\usepackage{tkz-graph}\n\\usepackage{tkz-berge}\n'
++    sage: latex.engine('pdflatex')
++    sage: latex.add_to_jsmath_avoid_list('tikzpicture')
++    sage: latex.jsmath_avoid_list()
++    ['tikzpicture']
++
++Agora, um comando como ``view(graphs.CompleteGraph(4))`` deve produzir
++um gráfico do grafo no Notebook, tendo usado ``pdflatex`` para
++processar os comandos do ``tkz-graph`` para construir o grafo. Note
++que há diversas opções que afetam o resultado do gráfico obtido usando
++o LaTeX via ``tkz-graph``, o que mais uma vez está além do escopo
++desta seção (veja a seção do Manual de Referência com título "Opções
++do LaTeX para Grafos" para instruções e detalhes).
++
++.. _sec-system-wide-tex:
++
++Uma Instalação Completa do TeX
++==============================
++Vários dos recursos avançados de integração do TeX com o Sage requerem
++uma instalação do TeX em seu sistema. Várias versões do Linux possuem
++pacotes do TeX baseados no TeX-live, para o OSX existe o TeXshop e
++para o windows existe o MikTex. O utilitário ``convert`` é parte do 
++`ImageMagick <http://www.imagemagick.org/>`_ (que deve ser um pacote
++na sua versão do Linux ou ser fácil de instalar), e os três programas
++``dvipng``, ``ps2pdf``, e ``dvips`` podem estar incluídos na sua
++distribuição do TeX. Os dois primeiros podem também ser obtidos em,
++respectivamente, http://sourceforge.net/projects/dvipng/ e como parte
++do `Ghostscript <http://www.ghostscript.com/>`_.
++
++A criação de grafos combinatoriais requer uma versão recente da
++biblioteca PGF, e os arquivos ``tkz-graph.sty``, ``tkz-arith.sty`` e
++talvez ``tkz-berge.sty``, que estão disponíveis em `Altermundus site
++<http://altermundus.com/pages/graph.html>`_.
++
++Programas Externos
++==================
++
++Existem três programas disponíveis para integrar ainda mais o TeX e o
++Sage. O primeiro é o sagetex. Uma descrição concisa do sagetex é que
++ele é uma coleção de macros do TeX que permitem incluir em um
++documento LaTeX instruções para usar o Sage para calcular vários
++objetos, e/ou formatar objetos usando o comando ``latex()`` existente
++no Sage. Logo, como um passo intermediário para compilar um documento
++LaTeX, todos os recursos computacionais e de formatação do Sage podem
++ser executados automaticamente. Como um exemplo, um exame matemático
++pode manter uma correspondência entre questões e respostas usando o
++sagetex para fazer cálculos com o Sage. Veja :ref:`sec-sagetex` para
++mais informações.
++
++O tex2sws começa com um documento LaTeX, mas define environments
++adicionais para inserir código em Sage. Quando processado com as
++ferramentas adequadas, o resultado é uma folha de trabalho do Sage,
++com conteúdo apropriadamente formatado para o jsMath e com código em
++Sage incorporado como células de entrada. Então um livro texto ou
++artigo pode ser criado em LaTeX, ter blocos de código em Sage
++incluídos, e o documento todo pode ser transformado em uma folha de
++trabalho do Sage onde o texto matemático é bem formatado e os blocos
++de código em Sage podem ser facilmente executados. Atualmente em
++desenvolvimento, veja `tex2sws @ BitBucket
++<http://bitbucket.org/rbeezer/tex2sws/>`_ para mais informações.
++
++O sws2tex reverte o processo partindo de uma folha de trabalho do Sage
++e convertendo o conteúdo para LaTeX para ser posteriormente processado
++com as ferramentas disponíveis para documentos em LaTeX. Atualmente em
++desenvolvimento, veja `sws2tex @ BitBucket
++<http://bitbucket.org/whuss/sws2tex/>`_ para mais informações.
+diff --git a/doc/pt/tutorial/programming.rst b/doc/pt/tutorial/programming.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/programming.rst
+@@ -0,0 +1,850 @@
++***********
++Programação
++***********
++
++.. _section-loadattach:
++
++Carregando e Anexando Arquivos do Sage
++======================================
++
++A seguir ilustramos como carregar no Sage programas escritos em um
++arquivo separado. Crie um arquivo chamado ``example.sage`` com o
++seguinte conteúdo:
++
++.. skip
++
++::
++
++    print "Hello World"
++    print 2^3
++
++Você pode ler e executar o arquivo ``example.sage`` usando o comando
++``load``.
++
++.. skip
++
++::
++
++    sage: load "example.sage"
++    Hello World
++    8
++
++Você também pode anexar um arquivo em Sage à sessão em execução usando
++o comando ``attach``.
++
++.. skip
++
++::
++
++    sage: attach "example.sage"
++    Hello World
++    8
++
++Agora se você alterar ``example.sage`` e adicionar uma linha em branco
++(por exemplo), então o conteúdo de ``example.sage`` será
++automaticamente recarregado no Sage.
++
++Em particular, ``attach`` automaticamente recarrega um arquivo toda
++vez que ele for modificado, o que é útil para desenvolver e testar um
++programa, enquanto ``load`` carrega o arquivo apenas uma vez.
++
++Quando o Sage carrega ``example.sage`` ele converte esse arquivo para
++o Python, o qual é então executado pelo interpretador do Python. Essa
++conversão é mínima; ela essencialmente consiste em encapsular inteiros
++em ``Integer()``, números float em ``RealNumber()``, substituir ``^``
++por ``**``, e substituir, por exemplo, ``R.2`` por ``R.gen(2)``. A
++versão convertida de ``example.sage`` é armazenada no mesmo diretório
++de ``example.sage`` e é chamada ``example.sage.py``. Esse arquivo
++contém o seguinte código:
++
++::
++
++    print "Hello World"
++    print Integer(2)**Integer(3)
++
++Inteiros literais são encapsulados e ``^`` é substituído por ``**``.
++(Em Python, ``^`` significa "ou exclusivo" e ``**`` significa
++"exponenciação".)
++
++Esse "preparsing" está implementado em ``sage/misc/interpreter.py``.)
++
++Você pode colar código tabulado com muitas linhas no Sage desde que
++existam linhas em branco separando blocos de código (isso não é
++necessário em arquivos). Todavia, a melhor forma de adicionar tal
++código a uma sessão do Sage é salvá-lo em um arquivo e usar
++``attach``, como descrito anteriormente.
++
++
++.. _section-compile:
++
++Criando Código Compilado
++========================
++
++Velocidade é crucial em cálculos matemáticos. Embora o Python seja uma
++linguagem conveniente de alto nível, certos cálculos podem ser várias
++vezes mais rápidos do que em Python se eles forem implementados usando
++tipos estáticos em uma linguagem compilada. Alguns aspectos do Sage
++seriam muito lentos se eles fossem escritos inteiramente em Python.
++Para lidar com isso, o Sage suporta uma "versão" compilada do Python
++chamada Cython ([Cyt]_ and [Pyr]_). O Cython é simultaneamente similar
++ao Python e ao C. A maior parte das construções em Python, incluindo
++"list comprehensions", expressões condicionais, código como ``+=`` são
++permitidos; você também pode importar código que você escreveu em
++outros módulos em Python. Além disso, você pode declarar variáveis em
++C arbitrárias, e qualquer chamada de bibliotecas em C pode ser feita
++diretamente. O código resultante é convertido para C e compilado
++usando um compilador para C.
++
++Para criar o seu próprio código compilado em Sage, nomeie o arquivo
++com uma extensão ``.spyx`` (em vez de ``.sage``). Se você está
++trabalhando na linha de comando, você pode anexar e carregar código
++compilado exatamente como se faz com código interpretado (no momento,
++anexar e carregar código em Cython não é suportado no Notebook). A
++compilação é realizada implicitamente sem que você tenha que fazer
++qualquer coisa explicitamente. Veja
++``$SAGE_ROOT/examples/programming/sagex/factorial.spyx`` para um
++exemplo de uma implementação compilada para a função fatorial que usa
++diretamente a biblioteca GMP em C. Experimente o seguinte, usando cd,
++vá para o diretório ``$SAGE_ROOT/examples/programming/sagex/``, e
++então faça o seguinte:
++
++.. skip
++
++::
++
++    sage: load "factorial.spyx"
++    ***************************************************
++                    Recompiling factorial.spyx
++    ***************************************************
++    sage: factorial(50)
++    30414093201713378043612608166064768844377641568960512000000000000L
++    sage: time n = factorial(10000)
++    CPU times: user 0.03 s, sys: 0.00 s, total: 0.03 s
++    Wall time: 0.03
++
++Aqui o sufixo L indica um "long integer" do Python (veja
++:ref:`section-mathannoy`).
++
++Note que o Sage vai recompilar ``factorial.spyx`` se você encerrar e
++reiniciar o Sage. A biblioteca compilada e compartilhada é armazenada
++em ``$HOME/.sage/temp/hostname/pid/spyx``. Esses arquivos são
++excluídos quando você encerra o Sage.
++
++Nenhum pré-processador (preparsing) é aplicado em arquivos spyx, por
++exemplo, ``1/3`` vai resultar em 0 em um arquivo spyx em vez do número
++racional :math:`1/3`. Se ``foo`` é uma função da biblioteca Sage, para
++usá-la em um arquivo spyx importe ``sage.all`` e use ``sage.all.foo``.
++
++::
++
++    import sage.all
++    def foo(n):
++        return sage.all.factorial(n)
++
++Acessando Funções em C em Arquivos Separados
++--------------------------------------------
++
++É fácil também acessar funções em C definidas em arquivos \*.c
++separados. Aqui vai um exemplo. Crie os arquivos ``test.c`` e
++``test.spyx`` no mesmo diretório contendo:
++
++Código C puro: ``test.c``
++
++::
++
++    int add_one(int n) {
++      return n + 1;
++    }
++
++Código Cython: ``test.spyx``:
++
++::
++
++    cdef extern from "test.c":
++        int add_one(int n)
++    
++    def test(n):
++        return add_one(n)
++
++Então o seguinte funciona:
++
++.. skip
++
++::
++
++    sage: attach "test.spyx"
++    Compiling (...)/test.spyx...
++    sage: test(10)
++    11
++
++Se uma biblioteca ``foo`` adicional é necessária para compilar código
++em C gerado a partir de um arquivo em Cython, adicione a linha ``clib
++foo`` no arquivo fonte em Cython. De forma similar, um arquivo em C
++adicional ``bar`` pode ser incluído na compilação declarando ``cfile
++bar``.
++
++.. _section-standalone:
++
++Scripts Independentes em Python/Sage
++====================================
++
++O seguinte script em Sage fatora inteiros, polinômios, etc:
++
++::
++
++    #!/usr/bin/env sage -python
++    
++    import sys
++    from sage.all import *
++    
++    if len(sys.argv) != 2:
++        print "Usage: %s <n>"%sys.argv[0]
++        print "Outputs the prime factorization of n."
++        sys.exit(1)
++    
++    print factor(sage_eval(sys.argv[1]))
++
++Para usar esse script, sua ``SAGE_ROOT`` precisa estar na sua variável
++PATH. Se o script acima for chamado ``factor``, aqui está um exemplo
++de como usá-lo:
++
++::
++
++    bash $ ./factor 2006
++    2 * 17 * 59
++    bash $ ./factor "32*x^5-1"
++    (2*x - 1) * (16*x^4 + 8*x^3 + 4*x^2 + 2*x + 1)
++
++Tipo de Dados
++=============
++
++Cada objeto em Sage possui um tipo bem definido. O Python possui
++diversos tipos de dados, e a biblioteca do Sage adiciona ainda mais.
++Os tipos de dados de Python incluem strings, listas, tuplas, inteiros
++e floats, como ilustrado:
++
++::
++
++    sage: s = "sage"; type(s)
++    <type 'str'>
++    sage: s = 'sage'; type(s)      # you can use either single or double quotes
++    <type 'str'>
++    sage: s = [1,2,3,4]; type(s)
++    <type 'list'>
++    sage: s = (1,2,3,4); type(s)
++    <type 'tuple'>
++    sage: s = int(2006); type(s)
++    <type 'int'>
++    sage: s = float(2006); type(s)
++    <type 'float'>
++
++Além disso, o Sage acrescenta vários outros tipos. Por exemplo,
++espaços vetoriais:
++
++::
++
++    sage: V = VectorSpace(QQ, 1000000); V
++    Vector space of dimension 1000000 over Rational Field
++    sage: type(V)
++    <class 'sage.modules.free_module.FreeModule_ambient_field_with_category'>
++
++Apenas certas funções podem ser aplicadas sobre ``V``. Em outros
++softwares de matemática, essas seriam chamadas usando a notação
++"funcional" ``foo(V,...)``. Em Sage, algumas funções estão anexadas ao
++tipo (ou classe) de ``V``, e são chamadas usando uma sintaxe orientada
++a objetos como em Java ou C++, por exemplo, ``V.foo()``. Isso ajuda a
++manter o espaço de variáveis global sem milhares de funções, e permite
++que várias funções diferentes com comportamento diferente possam ser
++chamadas foo, sem a necessidade de usar um mecanismo de identificação
++de tipos (ou casos) para decidir qual chamar. Além disso, se você
++reutilizar o nome de uma função, essa função continua ainda disponível
++(por exemplo, se você chamar algo ``zeta``, e então quiser calcular o
++valor da função zeta de Riemann em 0.5, você continua podendo digitar
++``s=.5; s.zeta()``).
++
++::
++
++    sage: zeta = -1
++    sage: s=.5; s.zeta()     
++    -1.46035450880959
++
++Em alguns casos muito comuns, a notação funcional usual é também
++suportada por conveniência e porque expressões matemáticas podem
++parecer confusas usando a notação orientada a objetos. Aqui vão alguns
++exemplos.
++
++::
++
++    sage: n = 2; n.sqrt()
++    sqrt(2)
++    sage: sqrt(2)
++    sqrt(2)
++    sage: V = VectorSpace(QQ,2)
++    sage: V.basis()
++        [
++        (1, 0),
++        (0, 1)
++        ]
++    sage: basis(V)
++        [
++        (1, 0),
++        (0, 1)
++        ]
++    sage: M = MatrixSpace(GF(7), 2); M
++    Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7
++    sage: A = M([1,2,3,4]); A
++    [1 2]
++    [3 4]
++    sage: A.charpoly('x')
++    x^2 + 2*x + 5
++    sage: charpoly(A, 'x')
++    x^2 + 2*x + 5
++
++Para listar todas as funções para :math:`A`, use completamento tab.
++Simplesmente digite ``A.``, então tecle ``[tab]`` no seu teclado, como
++descrito em :ref:`section-tabcompletion`.
++
++Listas, Tuplas e Sequências
++===========================
++
++O tipo de dados lista armazena elementos de um tipo arbitrário. Como
++em C, C++, etc. (mas diferentemente da maioria dos sistemas de álgebra
++computacional), os elementos da lista são indexados a partir do
++:math:`0`:
++
++::
++
++    sage: v = [2, 3, 5, 'x', SymmetricGroup(3)]; v
++    [2, 3, 5, 'x', Symmetric group of order 3! as a permutation group]
++    sage: type(v)
++    <type 'list'>
++    sage: v[0]
++    2
++    sage: v[2]
++    5
++
++(Quando se indexa uma lista, é permitido que o índice não seja um int
++do Python!) Um Inteiro do Sage (ou Racional, ou qualquer objeto que
++possua um método ``__index__``) também ira funcionar.
++
++::
++
++    sage: v = [1,2,3]
++    sage: v[2]
++    3
++    sage: n = 2      # SAGE Integer
++    sage: v[n]       # Perfectly OK!
++    3
++    sage: v[int(n)]  # Also OK.
++    3
++
++A função ``range`` cria uma lista de int's do Python (não Inteiros do
++Sage):
++
++::
++
++    sage: range(1, 15)
++    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
++
++Isso é útil quando se usa "list comprehensions" para construir listas:
++
++::
++
++    sage: L = [factor(n) for n in range(1, 15)]
++    sage: print L
++    [1, 2, 3, 2^2, 5, 2 * 3, 7, 2^3, 3^2, 2 * 5, 11, 2^2 * 3, 13, 2 * 7]
++    sage: L[12]
++    13
++    sage: type(L[12])
++    <class 'sage.structure.factorization_integer.IntegerFactorization'>
++    sage: [factor(n) for n in range(1, 15) if is_odd(n)]
++    [1, 3, 5, 7, 3^2, 11, 13]
++
++Para mais sobre como criar listas usando "list comprehensions", veja
++[PyT]_.
++
++Fatiamento de lista (list slicing) é um recurso fantástico. Se ``L`` é
++uma lista, então ``L[m:n]`` retorna uma sub-lista de ``L`` obtida
++começando do :math:`m`-ésimo elemento e terminando no
++:math:`(n-1)`-ésimo elemento, como ilustrado abaixo.
++
++::
++
++    sage: L = [factor(n) for n in range(1, 20)]
++    sage: L[4:9]
++    [5, 2 * 3, 7, 2^3, 3^2]
++    sage: print L[:4]
++    [1, 2, 3, 2^2]
++    sage: L[14:4]
++    []
++    sage: L[14:]
++    [3 * 5, 2^4, 17, 2 * 3^2, 19]
++
++Tuplas são semelhantes à listas, exceto que elas são imutáveis: uma
++vez criadas elas não podem ser alteradas.
++
++::
++
++    sage: v = (1,2,3,4); v
++    (1, 2, 3, 4)
++    sage: type(v)
++    <type 'tuple'>
++    sage: v[1] = 5
++    Traceback (most recent call last):
++    ...   
++    TypeError: 'tuple' object does not support item assignment
++
++Sequências são um terceiro tipo de dados do Sage semelhante a listas.
++Diferentemente de listas e tuplas, Sequence não é um tipo de dados
++nativo do Python. Por definição, uma sequência é mutável, mas usando o
++método ``set_immutable`` da classe ``Sequence`` elas podem ser feitas
++imutáveis, como mostra o exemplo a seguir. Todos os elementos da
++sequência possuem um parente comum, chamado o universo da sequência.
++
++::
++
++    sage: v = Sequence([1,2,3,4/5])
++    sage: v
++    [1, 2, 3, 4/5]
++    sage: type(v)
++    <class 'sage.structure.sequence.Sequence_generic'>
++    sage: type(v[1])
++    <type 'sage.rings.rational.Rational'>
++    sage: v.universe()
++    Rational Field
++    sage: v.is_immutable()
++    False
++    sage: v.set_immutable()
++    sage: v[0] = 3
++    Traceback (most recent call last):
++    ...
++    ValueError: object is immutable; please change a copy instead.
++
++Sequências são derivadas de listas e podem ser usadas em qualquer
++lugar que listas são usadas.
++
++::
++
++    sage: v = Sequence([1,2,3,4/5])
++    sage: isinstance(v, list)
++    True
++    sage: list(v)
++    [1, 2, 3, 4/5]
++    sage: type(list(v))
++    <type 'list'>
++
++Como um outro exemplo, bases para espaços vetoriais são sequências
++imutáveis, pois é importante que elas não sejam modificadas.
++
++::
++
++    sage: V = QQ^3; B = V.basis(); B
++    [
++    (1, 0, 0),
++    (0, 1, 0),
++    (0, 0, 1)
++    ]
++    sage: type(B)
++    <class 'sage.structure.sequence.Sequence_generic'>
++    sage: B[0] = B[1]
++    Traceback (most recent call last):
++    ...
++    ValueError: object is immutable; please change a copy instead.
++    sage: B.universe()
++    Vector space of dimension 3 over Rational Field
++
++Dicionários
++===========
++
++Um dicionário (também chamado as vezes de lista associativa) é um
++mapeamento de objetos "hashable" em objetos arbitrários. (Exemplos de
++objetos "hashable" são strings e números; veja a documentação Python
++em http://docs.python.org/tut/node7.html e
++http://docs.python.org/lib/typesmapping.html para detalhes).
++
++::
++
++    sage: d = {1:5, 'sage':17, ZZ:GF(7)}
++    sage: type(d)
++    <type 'dict'>
++    sage: d.keys()
++     [1, 'sage', Integer Ring]
++    sage: d['sage']
++    17
++    sage: d[ZZ]
++    Finite Field of size 7
++    sage: d[1]
++    5
++
++A terceira chave (key) ilustra como os índices de um dicionário podem
++ser complicados, por exemplo, um anel de inteiros.
++
++Você pode transformar o dicionário acima em uma lista com os mesmos
++dados:
++
++.. link
++
++::
++
++    sage: d.items()
++    [(1, 5), ('sage', 17), (Integer Ring, Finite Field of size 7)]
++
++É comum iterar sobre os pares em um dicionário:
++
++:: 
++
++    sage: d = {2:4, 3:9, 4:16}
++    sage: [a*b for a, b in d.iteritems()]
++    [8, 27, 64]
++
++Um dicionário não possui ordem, como o exemplo acima mostra.
++
++Conjuntos
++=========
++
++O Python possui um tipo set (conjuntos) nativo. O principal recurso
++que ele oferece é a rápida verificação se um objeto está ou não em um
++conjunto, juntamente com as operações comuns em conjuntos.
++
++::
++
++    sage: X = set([1,19,'a']);   Y = set([1,1,1, 2/3])
++    sage: X
++    set(['a', 1, 19])
++    sage: Y
++    set([1, 2/3])
++    sage: 'a' in X
++    True
++    sage: 'a' in Y
++    False
++    sage: X.intersection(Y)
++    set([1])
++
++O Sage também possui o seu próprio tipo de dados para conjuntos que é
++(em alguns casos) implementado usando o tipo nativo do Python, mas
++possuir algumas funcionalidades adicionais. Crie um conjunto em Sage
++usando ``Set(...)``. Por exemplo,
++
++::
++
++    sage: X = Set([1,19,'a']);   Y = Set([1,1,1, 2/3])
++    sage: X
++    {'a', 1, 19}
++    sage: Y
++    {1, 2/3}
++    sage: X.intersection(Y)
++    {1}
++    sage: print latex(Y)
++    \left\{1, \frac{2}{3}\right\}
++    sage: Set(ZZ)
++    Set of elements of Integer Ring
++
++Iteradores
++==========
++
++Iteradores foram adicionados recentemente ao Python e são
++particularmente úteis em aplicações matemáticas. Aqui estão vários
++exemplos; veja [PyT]_ para mais detalhes. Vamos criar um iterador
++sobre o quadrados dos números inteiros até :math:`10000000`.
++
++::
++
++    sage: v = (n^2 for n in xrange(10000000))
++    sage: v.next()
++    0
++    sage: v.next()
++    1
++    sage: v.next()
++    4
++
++Criamos agora um iterador sobre os primos da forma :math:`4p+1` com
++:math:`p` também primo, e observamos os primeiros valores.
++
++::
++
++    sage: w = (4*p + 1 for p in Primes() if is_prime(4*p+1))
++    sage: w         # in the next line, 0xb0853d6c is a random 0x number
++    <generator object at 0xb0853d6c>
++    sage: w.next()
++    13
++    sage: w.next()
++    29
++    sage: w.next()
++    53
++
++Certos anéis, por exemplo, corpos finitos e os inteiros possuem
++iteradores associados a eles:
++
++::
++
++    sage: [x for x in GF(7)]
++    [0, 1, 2, 3, 4, 5, 6]
++    sage: W = ((x,y) for x in ZZ for y in ZZ)
++    sage: W.next()
++    (0, 0)
++    sage: W.next()
++    (0, 1)
++    sage: W.next()
++    (0, -1)
++
++Laços, Funções, Enunciados de Controle e Comparações
++====================================================
++
++Nós já vimos alguns exemplos de alguns usos comuns de laços (loops)
++``for``. Em Python, um laço ``for`` possui uma estrutura tabulada, tal
++como
++
++::
++
++    >>> for i in range(5):
++           print(i)
++       
++    0
++    1
++    2
++    3
++    4
++
++Note que os dois pontos no final do enunciado (não existe "do" ou "od"
++como no GAP ou Maple), e a identação antes dos comandos dentro do
++laço, isto é, ``print(i)``. A tabulação é importante. No Sage, a
++tabulação é automaticamente adicionada quando você digita ``enter``
++após ":", como ilustrado abaixo.
++
++::
++
++    sage: for i in range(5):
++    ...       print(i)  # now hit enter twice
++    0
++    1
++    2
++    3
++    4
++
++O símbolo ``=`` é usado para atribuição.
++O símbolo ``==`` é usado para verificar igualdade:
++
++::
++
++    sage: for i in range(15):
++    ...       if gcd(i,15) == 1:
++    ...           print(i)
++    1
++    2
++    4
++    7
++    8
++    11
++    13
++    14
++
++Tenha em mente como a tabulação determina a estrutura de blocos para
++enunciados ``if``, ``for``, e ``while``:
++
++::
++
++    sage: def legendre(a,p):
++    ...       is_sqr_modp=-1
++    ...       for i in range(p):
++    ...           if a % p == i^2 % p:
++    ...               is_sqr_modp=1
++    ...       return is_sqr_modp
++             
++    sage: legendre(2,7)
++    1
++    sage: legendre(3,7)
++    -1
++
++Obviamente essa não é uma implementação eficiente do símbolo de
++Legendre! O objetivo é ilustrar vários aspectos da programação em
++Python/Sage. A função {kronecker}, que já vem com o Sage, calcula o
++símbolo de Legendre eficientemente usando uma biblioteca em C do PARI.
++
++Finalmente, observamos que comparações, tais como ``==``, ``!=``,
++``<=``, ``>=``, ``>``, ``<``, entre números irão automaticamente
++converter ambos os números para o mesmo tipo, se possível:
++
++::
++
++    sage: 2 < 3.1; 3.1 <= 1
++    True
++    False
++    sage: 2/3 < 3/2;   3/2 < 3/1
++    True
++    True
++
++Quase todos pares de objetos podem ser comparados; não se supõe que os
++objetos estejam equipados com uma ordem total.
++
++::
++
++    sage: 2 < CC(3.1,1)
++    True
++    sage: 5 < VectorSpace(QQ,3)   # output can be somewhat random
++    True
++
++Use bool para desigualdades simbólicas:
++
++::
++
++    sage: x < x + 1
++    x < x + 1
++    sage: bool(x < x + 1)
++    True
++
++Quando se compara objetos de tipos diferentes no Sage, na maior parte
++dos casos o Sage tenta encontrar uma coação canônica para ambos os
++objetos em um parente comum (veja :ref:`section-coercion` para mais
++detalhes). Se isso for bem sucedido, a comparação é realizada entre os
++objetos que foram coagidos; se não for bem sucedido, os objetos são
++considerados diferentes. Para testar se duas variáveis fazem
++referência ao mesmo objeto use ``is``. Como se vê no próximo exemplo,
++o int ``1`` do Python é único, mas o Inteiro ``1`` do Sage não é.
++
++::
++
++    sage: 1 is 2/2
++    False
++    sage: int(1) is int(2)/int(2)
++    True
++    sage: 1 is 1
++    False
++    sage: 1 == 2/2
++    True
++
++Nas duas linhas seguintes, a primeira igualdade é falsa (``False``)
++porque não existe um morfismo canônico :math:`QQ\to \GF{5}`, logo
++não há uma forma de comparar o :math:`1` em :math:`\GF{5}` com o
++:math:`1 \in \QQ`. Em contraste, existe um mapa canônico entre
++:math:`\ZZ \to \GF{5}`, logo a segunda comparação é verdadeira
++(``True``)
++
++::
++
++    sage: GF(5)(1) == QQ(1); QQ(1) == GF(5)(1)
++    False
++    False
++    sage: GF(5)(1) == ZZ(1); ZZ(1) == GF(5)(1)
++    True
++    True
++    sage: ZZ(1) == QQ(1)
++    True
++
++ATENÇÃO: Comparação no Sage é mais restritiva do que no Magma, o qual
++declara :math:`1 \in \GF{5}` igual a :math:`1 \in \QQ`.
++
++::
++
++    sage: magma('GF(5)!1 eq Rationals()!1')            # optional magma required
++    true
++
++Otimização (Profiling)
++======================
++
++Autor desta seção: Martin Albrecht (malb at informatik.uni-bremen.de)
++
++    "Premature optimization is the root of all evil." - Donald Knuth
++
++As vezes é útil procurar por gargalos em programas para entender quais
++partes gastam maior tempo computacional; isso pode dar uma boa ideia
++sobre quais partes otimizar. Python e portanto Sage fornecem várias
++opções de "profiling" (esse é o nome que se dá ao processo de
++otimização).
++
++O mais simples de usar é o comando ``prun`` na linha de comando
++interativa. Ele retorna um sumário sobre o tempo computacional
++utilizado por cada função. Para analisar (a atualmente lenta! -- na
++versão 1.0) multiplicação de matrizes sobre corpos finitos, por
++exemplo, faça o seguinte:
++
++::
++
++    sage: k,a = GF(2**8, 'a').objgen()
++    sage: A = Matrix(k,10,10,[k.random_element() for _ in range(10*10)])
++
++.. skip
++
++::
++
++    sage: %prun B = A*A
++           32893 function calls in 1.100 CPU seconds
++    
++    Ordered by: internal time
++    
++    ncalls tottime percall cumtime percall filename:lineno(function)
++     12127  0.160   0.000   0.160  0.000 :0(isinstance)
++      2000  0.150   0.000   0.280  0.000 matrix.py:2235(__getitem__)
++      1000  0.120   0.000   0.370  0.000 finite_field_element.py:392(__mul__)
++      1903  0.120   0.000   0.200  0.000 finite_field_element.py:47(__init__)
++      1900  0.090   0.000   0.220  0.000 finite_field_element.py:376(__compat)
++       900  0.080   0.000   0.260  0.000 finite_field_element.py:380(__add__)
++         1  0.070   0.070   1.100  1.100 matrix.py:864(__mul__)
++      2105  0.070   0.000   0.070  0.000 matrix.py:282(ncols)
++      ...
++
++Aqui ``ncalls`` é o números de chamadas, ``tottime`` é o tempo total
++gasto por uma determinada função (excluíndo o tempo gasto em chamadas
++de subfunções), ``percall`` é o quociente de ``tottime`` dividido por
++``ncalls``. ``cumtime`` é o tempo total gasto nessa e em todas as
++subfunções (isto é, desde o início até o término da execução da
++função), ``percall`` é o quociente de ``cumtime`` dividido pelas
++chamadas primitivas, e ``filename:lineno(function)`` fornece os dados
++respectivos para cada função. A regra prática aqui é: Quanto mais no
++topo uma função aparece nessa lista, mais custo computacional ela
++acarreta. Logo é mais interessante para ser optimizada.
++
++Como usual, ``prun?`` fornece detalhes sobre como usar o "profiler" e
++como entender a saída de dados.
++
++A saída de dados pode ser escrita em um objeto para permitir uma
++análise mais detalhada:
++
++.. skip
++
++::
++
++    sage: %prun -r A*A
++    sage: stats = _
++    sage: stats?
++
++Note: digitando ``stats = prun -r A\*A`` obtém-se um erro de sintaxe
++porque prun é um comando do IPython, não uma função comum.
++
++Para uma representação gráfica dos dados do "profiling", você pode
++usar o "hotspot profiler", um pequeno script chamado
++``hotshot2cachetree`` e o programa ``kcachegrind`` (apenas no Unix). O
++mesmo exemplo agora com o "hotspot profiler":
++
++.. skip
++
++::
++
++    sage: k,a = GF(2**8, 'a').objgen()
++    sage: A = Matrix(k,10,10,[k.random_element() for _ in range(10*10)])
++    sage: import hotshot
++    sage: filename = "pythongrind.prof"
++    sage: prof = hotshot.Profile(filename, lineevents=1)
++
++.. skip
++
++::
++
++    sage: prof.run("A*A")
++    <hotshot.Profile instance at 0x414c11ec>
++    sage: prof.close()
++
++Isso resulta em um arquivo ``pythongrind.prof`` no diretório de
++trabalho atual. Ele pode ser convertido para o formato cachegrind para
++visualização.
++
++Em uma linha de comando do sistema, digite
++
++.. skip
++
++::
++
++    hotshot2calltree -o cachegrind.out.42 pythongrind.prof
++
++O arquivo de saída ``cachegrind.out.42`` pode ser examinado com
++``kcachegrind``. Note que a convenção de nomes ``cachegrind.out.XX``
++precisa ser obedecida.
+diff --git a/doc/pt/tutorial/sagetex.rst b/doc/pt/tutorial/sagetex.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/sagetex.rst
+@@ -0,0 +1,112 @@
++.. _sec-sagetex:
++
++****************
++Usando o SageTeX
++****************
++
++O pacote SageTeX permite que você insira resultados de cálculos feitos
++com o Sage em um documento LaTeX. Esse pacote já vem com o Sage. Para
++usá-lo, você precisa "instalá-lo" em seu sistema LaTeX local; aqui
++instalar significa copiar um simples arquivo. Veja :ref:`installation`
++neste tutorial e a seção "Make SageTeX known to TeX" do `Guia de
++instalação do Sage <http://sagemath.org/doc/installation/index.html>`_
++(em inglês) (`este link <../installation/index.html>`_ deve levá-lo a
++uma cópia local do guia de instalação para mais informações de como
++proceder.
++
++Aqui vai um breve exemplo de como usar o SageTeX. A documentação
++completa pode ser encontrada em
++``SAGE_ROOT/local/share/texmf/tex/generic/sagetex``, onde
++``SAGE_ROOT`` é o diretório onde se encontra a sua instalação. Esse
++diretório contém a documentação, um arquivo de exemplo, e alguns
++scripts em Python possivelmente úteis.
++
++Para ver como o SageTeX funciona, siga as instruções para instalar o
++SageTeX (em :ref:`installation`) e copie o seguinte texto em um
++arquivo chamado ``st_example.tex``, por exemplo.
++
++.. warning::
++
++  O texto abaixo vai apresentar diversos erros sobre "unknown control
++  sequences" se você está visualizando isto na ajuda "live". Use a
++  versão estática para ver o texto corretamente.
++
++.. code-block:: latex
++
++    \documentclass{article}
++    \usepackage{sagetex}
++
++    \begin{document}
++
++    Using Sage\TeX, one can use Sage to compute things and put them into
++    your \LaTeX{} document. For example, there are
++    $\sage{number_of_partitions(1269)}$ integer partitions of $1269$.
++    You don't need to compute the number yourself, or even cut and paste
++    it from somewhere.
++
++    Here's some Sage code:
++
++    \begin{sageblock}
++        f(x) = exp(x) * sin(2*x)
++    \end{sageblock}
++
++    The second derivative of $f$ is
++
++    \[
++      \frac{\mathrm{d}^{2}}{\mathrm{d}x^{2}} \sage{f(x)} =
++      \sage{diff(f, x, 2)(x)}.
++    \]
++
++    Here's a plot of $f$ from $-1$ to $1$:
++
++    \sageplot{plot(f, -1, 1)}
++
++    \end{document}
++
++Execute o LaTeX em ``st_example.tex`` da forma usual. Note que o LaTeX
++vai reclamar sobre algumas coisas, entre elas::
++
++    Package sagetex Warning: Graphics file
++    sage-plots-for-st_example.tex/plot-0.eps on page 1 does not exist. Plot
++    command is on input line 25.
++
++    Package sagetex Warning: There were undefined Sage formulas and/or
++    plots. Run Sage on st_example.sage, and then run LaTeX on
++    st_example.tex again.
++
++Observe que, além dos arquivos usuais produzidos pelo LaTeX, existe um
++arquivo chamado ``st_example.sage``. Esse é um script em Sage
++produzido quando você executa o LaTeX em ``st_example.tex``. A
++mensagem de alerta pede para você executar o LaTeX em
++``st_example.sage``, então siga essa sugestão e faça isso. Você vai
++receber uma mensagem para executar o LaTeX em ``st_example.tex``
++novamente, mas antes que você faça isso, observe que um novo arquivo
++foi criado: ``st_example.sout``. Esse arquivo contém os resultados dos
++cálculos feitos pelo Sage, em um formato que o LaTeX pode usar para
++inserir em seu texto. Um novo diretório contendo um arquivo EPS do seu
++gráfico também foi criado. Execute o LaTeX novamente e você vai ver
++que tudo que foi calculado, incluindo os gráficos, foi incluído em seu
++documento.
++
++As macros utilizadas acima devem ser fáceis de entender. Um
++environment ``sageblock`` insere código "verbatim" (exatamente como é
++digitado) e também executa o código quando você executa o Sage. Quando
++você insere ``\sage{foo}``, é incluído em seu documento o resultado
++que você obteria executando ``latex(foo)`` no Sage. Comandos para
++fazer gráficos são um pouco mais complicados, mas em sua forma mais
++simples, ``\sageplot{foo}`` insere a imagem que você obtêm usando
++``foo.save('filename.eps')``.
++
++Em geral, a rotina é a seguinte:
++
++    - execute o LaTeX no seu arquivo .tex;
++    - execute o Sage no arquivo .sage que foi gerado;
++    - execute o LaTeX novamente.
++
++Você pode omitir a execução do Sage desde que você não tenha alterado
++os comandos em Sage em seu documento.
++
++Há muito mais sobre o SageTeX, e como tanto o Sage como o LaTeX são
++ferramentas complexas e poderosas, é uma boa idéia ler a documentação
++para o SageTeX que se encontra em
++``SAGE_ROOT/local/share/texmf/tex/generic/sagetex``.
+diff --git a/doc/pt/tutorial/tour.rst b/doc/pt/tutorial/tour.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour.rst
+@@ -0,0 +1,31 @@
++*****************
++Um passeio guiado
++*****************
++
++Esta seção é um passeio guiado pelo que está disponível no Sage. Para
++diversos outros exemplos, veja "Construções em Sage", que tem como
++objetivo responder à questão geral "Como eu construo ...?". Veja
++também o "Sage Reference Manual", que possui centenas de outros
++exemplos. Note que é também possível percorrer este tutorial no Sage
++Notebook clicando no link ``Help``.
++
++(Se você está acessando este tutorial no Sage Notebook, pressione
++``shift-enter`` para processar qualquer célula de entrada. Você pode
++até editar a célula antes de pressionar ``shift-enter``. Em alguns
++Macs pode ser necessário pressionar ``shift-return`` em vez de
++``shift-enter``.)
++
++.. toctree::
++
++   tour_assignment
++   tour_help
++   tour_algebra
++   tour_plotting
++   tour_functions
++   tour_rings
++   tour_linalg
++   tour_polynomial
++   tour_coercion
++   tour_groups
++   tour_numtheory
++   tour_advanced
+diff --git a/doc/pt/tutorial/tour_advanced.rst b/doc/pt/tutorial/tour_advanced.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_advanced.rst
+@@ -0,0 +1,548 @@
++Um Pouco Mais de Matemática Avançada
++====================================
++
++Geometria Algébrica
++-------------------
++
++Você pode definir variedades algébricas arbitrárias no Sage, mas as
++vezes alguma funcionalidade não-trivial é limitada a anéis sobre
++:math:`\QQ` ou corpos finitos. Por exemplo, vamos calcular a união de
++duas curvas planas afim, e então recuperar as curvas como as
++componentes irredutíveis da união.
++
++::
++
++    sage: x, y = AffineSpace(2, QQ, 'xy').gens()
++    sage: C2 = Curve(x^2 + y^2 - 1)
++    sage: C3 = Curve(x^3 + y^3 - 1)
++    sage: D = C2 + C3
++    sage: D
++    Affine Curve over Rational Field defined by 
++       x^5 + x^3*y^2 + x^2*y^3 + y^5 - x^3 - y^3 - x^2 - y^2 + 1
++    sage: D.irreducible_components()
++    [
++    Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:
++      x^2 + y^2 - 1,
++    Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:
++      x^3 + y^3 - 1
++    ]
++
++Você também pode encontrar todos os pontos de interseção das duas
++curvas, intersectando-as, e então calculando as componentes
++irredutíveis.
++
++.. link
++
++::
++
++    sage: V = C2.intersection(C3)
++    sage: V.irreducible_components()
++    [
++    Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:
++      y - 1,
++      x,
++    Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:
++      y,
++      x - 1,
++    Closed subscheme of Affine Space of dimension 2 over Rational Field defined by:
++      x + y + 2,
++      2*y^2 + 4*y + 3
++    ]
++
++Portanto, por exemplo, :math:`(1,0)` e :math:`(0,1)` estão em ambas as
++curvas (o que é claramente visível), como também estão certos pontos
++(quadráticos) cuja coordenada :math:`y` satisfaz :math:`2y^2 + 4y +
++3=0`.
++
++O Sage pode calcular o ideal toroidal da cúbica torcida no espaço-3
++projetivo:
++
++::
++
++    sage: R.<a,b,c,d> = PolynomialRing(QQ, 4)
++    sage: I = ideal(b^2-a*c, c^2-b*d, a*d-b*c)
++    sage: F = I.groebner_fan(); F
++    Groebner fan of the ideal:
++    Ideal (b^2 - a*c, c^2 - b*d, -b*c + a*d) of Multivariate Polynomial Ring
++    in a, b, c, d over Rational Field
++    sage: F.reduced_groebner_bases ()
++    [[-c^2 + b*d, -b*c + a*d, -b^2 + a*c],
++     [c^2 - b*d, -b*c + a*d, -b^2 + a*c],
++     [c^2 - b*d, b*c - a*d, -b^2 + a*c, -b^3 + a^2*d],
++     [c^2 - b*d, b*c - a*d, b^3 - a^2*d, -b^2 + a*c],
++     [c^2 - b*d, b*c - a*d, b^2 - a*c],
++     [-c^2 + b*d, b^2 - a*c, -b*c + a*d],
++     [-c^2 + b*d, b*c - a*d, b^2 - a*c, -c^3 + a*d^2],
++     [c^3 - a*d^2, -c^2 + b*d, b*c - a*d, b^2 - a*c]]
++    sage: F.polyhedralfan()
++    Polyhedral fan in 4 dimensions of dimension 4
++
++Curvas Elípticas
++----------------
++
++A funcionalidade para curvas elípticas inclui a maior parte da
++funcionalidade para curvas elípticas do PARI, acesso aos dados da base
++de dados Cremona (isso requer um pacote adicional), os recursos do
++mwrank, isto é, "2-descends" com cálculos do grupo de Mordell-Weil
++completo, o algoritmo SEA (singla em inglês), cálculo de todas as
++isogenias, bastante código novo para curvas sobre :math:`\QQ`, e parte
++do software "algebraic descent" de Denis Simons.
++
++O comando ``EllipticCurve`` para criar curvas elípticas possui várias
++formas:
++
++
++-  EllipticCurve([:math:`a_1`, :math:`a_2`, :math:`a_3`, :math:`a_4`, :math:`a_6`]):
++   Fornece a curva elíptica
++
++   .. math::  y^2+a_1xy+a_3y=x^3+a_2x^2+a_4x+a_6,
++
++
++   onde os :math:`a_i`'s são coagidos para os parentes de :math:`a_1`.
++   Se todos os :math:`a_i` possuem parente :math:`\ZZ`, então eles são
++   coagidos para :math:`\QQ`.
++
++-  EllipticCurve([:math:`a_4`, :math:`a_6`]): Conforme acima, mas
++   :math:`a_1=a_2=a_3=0`.
++
++-  EllipticCurve(label): Fornece a curva elíptica da base de dados
++   Cremona com o "label" (novo) dado. O label é uma string, tal como
++   ``"11a"`` ou ``"37b2"``. As letras devem ser minúsculas (para
++   distinguir dos labels antigos).
++
++-  EllipticCurve(j): Fornece uma curva elíptica com invariante
++   :math:`j`.
++
++-  EllipticCurve(R,
++   [:math:`a_1`, :math:`a_2`, :math:`a_3`, :math:`a_4`, :math:`a_6`]):
++   Cria uma curva elíptica sobre um anel :math:`R` com os
++   :math:`a_i`'s.
++
++
++Agora ilustramos cada uma dessas construções:
++
++::
++
++    sage: EllipticCurve([0,0,1,-1,0])
++    Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
++    
++    sage: EllipticCurve([GF(5)(0),0,1,-1,0])
++    Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5
++    
++    sage: EllipticCurve([1,2])
++    Elliptic Curve defined by y^2  = x^3 + x + 2 over Rational Field
++    
++    sage: EllipticCurve('37a')
++    Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
++    
++    sage: EllipticCurve_from_j(1)
++    Elliptic Curve defined by y^2 + x*y = x^3 + 36*x + 3455 over Rational Field
++    
++    sage: EllipticCurve(GF(5), [0,0,1,-1,0])
++    Elliptic Curve defined by y^2 + y = x^3 + 4*x over Finite Field of size 5
++
++O par :math:`(0,0)` é um ponto na curva elíptica :math:`E` definida
++por :math:`y^2 + y = x^3 - x`. Para criar esse ponto digite
++``E([0,0])``. O Sage pode somar pontos em uma curva elíptica
++(lembre-se que é possível definir uma estrutura de grupo aditivo em
++curvas elípticas onde o ponto no infinito é o elemento nulo, e a some
++de três pontos colineares sobre a curva é zero):
++
++::
++
++    sage: E = EllipticCurve([0,0,1,-1,0])
++    sage: E
++    Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
++    sage: P = E([0,0])
++    sage: P + P
++    (1 : 0 : 1)
++    sage: 10*P
++    (161/16 : -2065/64 : 1)
++    sage: 20*P
++    (683916417/264517696 : -18784454671297/4302115807744 : 1)
++    sage: E.conductor()
++    37
++
++As curvas elípticas sobre os números complexos são parametrizadas
++pelo invariante :math:`j`. O Sage calcula o invariante :math:`j` da
++seguinte forma:
++
++::
++
++    sage: E = EllipticCurve([0,0,0,-4,2]); E
++    Elliptic Curve defined by y^2 = x^3 - 4*x + 2 over Rational Field
++    sage: E.conductor()
++    2368
++    sage: E.j_invariant()
++    110592/37      
++
++Se criarmos uma curva com o mesmo invariante :math:`j` que a curva
++:math:`E`, ela não precisa ser isomórfica a :math:`E`. No seguinte
++exemplo, as curvas não são isomórficas porque os seus condutores são
++diferentes.
++
++::
++
++    sage: F = EllipticCurve_from_j(110592/37)
++    sage: F.conductor()
++    37
++
++Todavia, uma torção de :math:`F` por um fator 2 resulta em uma curva
++isomórfica.
++
++.. link
++
++::
++
++    sage: G = F.quadratic_twist(2); G
++    Elliptic Curve defined by y^2 = x^3 - 4*x + 2 over Rational Field
++    sage: G.conductor()
++    2368
++    sage: G.j_invariant()
++    110592/37
++
++Nós podemos calcular os coeficientes :math:`a_n` de uma
++série-:math:`L` ou forma modular :math:`\sum_{n=0}^\infty
++a_nq^n` associada à curva elíptica. Esse cálculo usa a biblioteca C do
++PARI.
++
++::
++
++    sage: E = EllipticCurve([0,0,1,-1,0])
++    sage: print E.anlist(30)  
++    [0, 1, -2, -3, 2, -2, 6, -1, 0, 6, 4, -5, -6, -2, 2, 6, -4, 0, -12, 0, -4, 
++     3, 10, 2, 0, -1, 4, -9, -2, 6, -12]
++    sage: v = E.anlist(10000)    
++
++Leva apenas um segundo para calcular todos os :math:`a_n` para
++:math:`n\leq 10^5`:
++
++.. skip
++
++::
++
++    sage: %time v = E.anlist(100000)
++    CPU times: user 0.98 s, sys: 0.06 s, total: 1.04 s
++    Wall time: 1.06
++
++Curvas elípticas podem ser construídas usando o "label" da base de
++dados Cremona. Isso importa a curva elíptica com informações prévias
++sobre o seu posto, números de Tomagawa, regulador, etc.
++
++::
++
++    sage: E = EllipticCurve("37b2")
++    sage: E
++    Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational 
++    Field
++    sage: E = EllipticCurve("389a")
++    sage: E
++    Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x  over Rational Field
++    sage: E.rank()
++    2
++    sage: E = EllipticCurve("5077a")
++    sage: E.rank()
++    3
++
++Nós também podemos acessar a base de dados Cremona diretamente.
++
++::
++
++    sage: db = sage.databases.cremona.CremonaDatabase()
++    sage: db.curves(37)
++    {'a1': [[0, 0, 1, -1, 0], 1, 1], 'b1': [[0, 1, 1, -23, -50], 0, 3]}
++    sage: db.allcurves(37)
++    {'a1': [[0, 0, 1, -1, 0], 1, 1],
++     'b1': [[0, 1, 1, -23, -50], 0, 3],
++     'b2': [[0, 1, 1, -1873, -31833], 0, 1],
++     'b3': [[0, 1, 1, -3, 1], 0, 3]}
++
++Os objetos obtidos pela base de dados não são do tipo
++``EllipticCurve``. Eles são elementos de uma base de dados e possuem
++alguns campos, e apenas isso. Existe uma versão básica da base de
++dados Cremona, que já é distribuída na versão padrão do Sage, e contém
++informações limitadas sobre curvas elípticas de condutor :math:`\leq
++10000`. Existe também uma versão estendida opcional, que contém
++informações extensas sobre curvas elípticas de condutor :math:`\leq
++120000` (em outubro de 2005). Por fim, existe ainda uma versão (2GB)
++opcional de uma base de dados para o Sage que contém centenas de
++milhares de curvas elípticas na base de dados Stein-Watkins.
++
++Caracteres de Dirichlet
++-----------------------
++
++Um *caractere de Dirichlet* é a extensão de um homomorfismo
++:math:`(\ZZ/N\ZZ)* \to R^*`, para algum anel :math:`R`, para o mapa
++:math:`\ZZ \to R` obtido mapeando os inteiros :math:`x` tais que
++:math:`\gcd(N,x)>1` em 0.
++
++::
++
++    sage: G = DirichletGroup(12)
++    sage: G.list()
++    [Dirichlet character modulo 12 of conductor 1 mapping 7 |--> 1, 5 |--> 1, 
++    Dirichlet character modulo 12 of conductor 4 mapping 7 |--> -1, 5 |--> 1, 
++    Dirichlet character modulo 12 of conductor 3 mapping 7 |--> 1, 5 |--> -1, 
++    Dirichlet character modulo 12 of conductor 12 mapping 7 |--> -1, 5 |--> -1]
++    sage: G.gens()
++    (Dirichlet character modulo 12 of conductor 4 mapping 7 |--> -1, 5 |--> 1, 
++    Dirichlet character modulo 12 of conductor 3 mapping 7 |--> 1, 5 |--> -1)
++    sage: len(G)
++    4
++
++Tendo criado o grupo, a seguir calculamos um elemento e fazemos
++cálculos com ele.
++
++.. link
++
++::
++
++    sage: G = DirichletGroup(21)
++    sage: chi = G.1; chi
++    Dirichlet character modulo 21 of conductor 7 mapping 8 |--> 1, 10 |--> zeta6
++    sage: chi.values()
++    [0, 1, zeta6 - 1, 0, -zeta6, -zeta6 + 1, 0, 0, 1, 0, zeta6, -zeta6, 0, -1, 
++     0, 0, zeta6 - 1, zeta6, 0, -zeta6 + 1, -1]
++    sage: chi.conductor()
++    7
++    sage: chi.modulus()
++    21
++    sage: chi.order()
++    6
++    sage: chi(19)
++    -zeta6 + 1
++    sage: chi(40)
++    -zeta6 + 1
++
++É também possível calcular a ação do grupo de Galois
++:math:`\text{Gal}(\QQ(\zeta_N)/\QQ)` sobre esses caracteres, bem como
++a decomposição em produto direto correspondente à fatorização do
++módulo.
++
++.. link
++
++::
++
++    sage: chi.galois_orbit()
++    [Dirichlet character modulo 21 of conductor 7 mapping 8 |--> 1, 10 |--> zeta6, 
++    Dirichlet character modulo 21 of conductor 7 mapping 8 |--> 1, 10 |--> -zeta6 + 1]
++   
++    sage: go = G.galois_orbits()
++    sage: [len(orbit) for orbit in go]
++    [1, 2, 2, 1, 1, 2, 2, 1]
++    
++    sage: G.decomposition()
++    [
++    Group of Dirichlet characters of modulus 3 over Cyclotomic Field of order 
++    6 and degree 2,
++    Group of Dirichlet characters of modulus 7 over Cyclotomic Field of order 
++    6 and degree 2
++    ]
++
++A seguir, construímos o grupo de caracteres de Dirichlet mod 20, mas
++com valores em :math:`\QQ(i)`:
++
++::
++
++    sage: K.<i> = NumberField(x^2+1)
++    sage: G = DirichletGroup(20,K)
++    sage: G
++    Group of Dirichlet characters of modulus 20 over Number Field in i with defining polynomial x^2 + 1
++
++Agora calculamos diversos invariantes de ``G``:
++
++.. link
++
++::
++
++    sage: G.gens()
++    (Dirichlet character modulo 20 of conductor 4 mapping 11 |--> -1, 17 |--> 1,
++    Dirichlet character modulo 20 of conductor 5 mapping 11 |--> 1, 17 |--> i)
++
++    sage: G.unit_gens()
++    [11, 17]
++    sage: G.zeta()
++    i
++    sage: G.zeta_order()
++    4
++
++No próximo exemplo criamos um caractere de Dirichlet com valores em um
++corpo numérico. Nós especificamos explicitamente a escolha da raiz da
++unidade no terceiro argumento do comando ``DirichletGroup`` abaixo.
++
++::
++
++    sage: x = polygen(QQ, 'x')
++    sage: K = NumberField(x^4 + 1, 'a'); a = K.0
++    sage: b = K.gen(); a == b
++    True
++    sage: K
++    Number Field in a with defining polynomial x^4 + 1
++    sage: G = DirichletGroup(5, K, a); G
++    Group of Dirichlet characters of modulus 5 over Number Field in a with 
++    defining polynomial x^4 + 1
++    sage: chi = G.0; chi
++    Dirichlet character modulo 5 of conductor 5 mapping 2 |--> a^2
++    sage: [(chi^i)(2) for i in range(4)]
++    [1, a^2, -1, -a^2]
++
++Aqui ``NumberField(x^4 + 1, 'a')`` diz para o Sage usar o símbolo "a"
++quando imprimir o que é ``K`` (um corpo numérico definido pelo
++polinômio :math:`x^4 + 1`). O nome "a" não está declarado até então.
++Uma vez que ``a = K.0`` (ou equivalentemente ``a = K.gen()``) é
++calculado, o símbolo "a" representa a raiz do polinômio gerador
++:math:`x^4+1`.
++
++Formas Modulares
++----------------
++
++O Sage pode fazer alguns cálculos relacionados a formas modulares,
++incluindo dimensões, calcular espaços de símbolos modulares,
++operadores de Hecke, e decomposições.
++
++Existem várias funções disponíveis para calcular dimensões de espaços
++de formas modulares. Por exemplo,
++
++::
++
++    sage: dimension_cusp_forms(Gamma0(11),2)
++    1
++    sage: dimension_cusp_forms(Gamma0(1),12)
++    1
++    sage: dimension_cusp_forms(Gamma1(389),2)
++    6112
++
++A seguir ilustramos o cálculo dos operadores de Hecke em um espaço de
++símbolos modulares de nível :math:`1` e peso :math:`12`.
++
++::
++
++    sage: M = ModularSymbols(1,12)
++    sage: M.basis()
++    ([X^8*Y^2,(0,0)], [X^9*Y,(0,0)], [X^10,(0,0)])
++    sage: t2 = M.T(2)
++    sage: t2
++    Hecke operator T_2 on Modular Symbols space of dimension 3 for Gamma_0(1) 
++    of weight 12 with sign 0 over Rational Field
++    sage: t2.matrix()
++    [ -24    0    0]
++    [   0  -24    0]
++    [4860    0 2049]
++    sage: f = t2.charpoly('x'); f
++    x^3 - 2001*x^2 - 97776*x - 1180224
++    sage: factor(f)
++    (x - 2049) * (x + 24)^2
++    sage: M.T(11).charpoly('x').factor()
++    (x - 285311670612) * (x - 534612)^2
++
++Podemos também criar espaços para :math:`\Gamma_0(N)` e
++:math:`\Gamma_1(N)`.
++
++
++::
++
++    sage: ModularSymbols(11,2)
++    Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign
++     0 over Rational Field
++    sage: ModularSymbols(Gamma1(11),2)
++    Modular Symbols space of dimension 11 for Gamma_1(11) of weight 2 with 
++    sign 0 and over Rational Field
++
++Vamos calcular alguns polinômios característicos e expansões
++:math:`q`.
++
++::
++
++    sage: M = ModularSymbols(Gamma1(11),2)
++    sage: M.T(2).charpoly('x')
++    x^11 - 8*x^10 + 20*x^9 + 10*x^8 - 145*x^7 + 229*x^6 + 58*x^5 - 360*x^4 
++         + 70*x^3 - 515*x^2 + 1804*x - 1452
++    sage: M.T(2).charpoly('x').factor()
++    (x - 3) * (x + 2)^2 * (x^4 - 7*x^3 + 19*x^2 - 23*x + 11) 
++            * (x^4 - 2*x^3 + 4*x^2 + 2*x + 11)
++    sage: S = M.cuspidal_submodule()
++    sage: S.T(2).matrix()
++    [-2  0]
++    [ 0 -2]
++    sage: S.q_expansion_basis(10)
++    [
++        q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10)
++    ]
++
++Podemos até mesmo calcular espaços de símbolos modulares com carácter.
++
++::
++
++    sage: G = DirichletGroup(13)
++    sage: e = G.0^2
++    sage: M = ModularSymbols(e,2); M
++    Modular Symbols space of dimension 4 and level 13, weight 2, character 
++    [zeta6], sign 0, over Cyclotomic Field of order 6 and degree 2
++    sage: M.T(2).charpoly('x').factor()
++    (x - 2*zeta6 - 1) * (x - zeta6 - 2) * (x + zeta6 + 1)^2
++    sage: S = M.cuspidal_submodule(); S
++    Modular Symbols subspace of dimension 2 of Modular Symbols space of 
++    dimension 4 and level 13, weight 2, character [zeta6], sign 0, over 
++    Cyclotomic Field of order 6 and degree 2
++    sage: S.T(2).charpoly('x').factor()
++    (x + zeta6 + 1)^2
++    sage: S.q_expansion_basis(10)
++    [
++    q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 
++      + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10)
++    ]
++
++Aqui está um outro exemplo de como o Sage pode calcular a ação de
++operadores de Hecke em um espaço de formas modulares.
++
++::
++
++    sage: T = ModularForms(Gamma0(11),2)
++    sage: T
++    Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of 
++    weight 2 over Rational Field
++    sage: T.degree()
++    2
++    sage: T.level()
++    11
++    sage: T.group()
++    Congruence Subgroup Gamma0(11)
++    sage: T.dimension()
++    2
++    sage: T.cuspidal_subspace()
++    Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for
++    Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
++    sage: T.eisenstein_subspace()
++    Eisenstein subspace of dimension 1 of Modular Forms space of dimension 2 
++    for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
++    sage: M = ModularSymbols(11); M
++    Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign
++    0 over Rational Field
++    sage: M.weight()
++    2
++    sage: M.basis()
++    ((1,0), (1,8), (1,9))
++    sage: M.sign()
++    0
++
++Denote por :math:`T_p` os operadores de Hecke usuais (:math:`p`
++primo).  Como os operadores de Hecke :math:`T_2`, :math:`T_3`,
++e :math:`T_5` agem sobre o espaço de símbolos modulares?
++
++
++.. link
++
++::
++
++    sage: M.T(2).matrix()
++    [ 3  0 -1]
++    [ 0 -2  0]
++    [ 0  0 -2]
++    sage: M.T(3).matrix()
++    [ 4  0 -1]
++    [ 0 -1  0]
++    [ 0  0 -1]
++    sage: M.T(5).matrix()
++    [ 6  0 -1]
++    [ 0  1  0]
++    [ 0  0  1]
+diff --git a/doc/pt/tutorial/tour_algebra.rst b/doc/pt/tutorial/tour_algebra.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_algebra.rst
+@@ -0,0 +1,414 @@
++Álgebra Elementar e Cálculo
++===========================
++
++O Sage pode realizar diversos cálculos em álgebra elementar e cálculo
++diferencial e integral: por exemplo, encontrar soluções de equações,
++diferenciar, integrar, e calcular a transformada de Laplace. Veja a
++documentação em `Sage Constructions
++<http://www.sagemath.org/doc/constructions/>`_ para mais exemplos.
++
++Resolvendo equações
++-------------------
++
++Resolvendo equações exatamente
++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++
++A função ``solve`` resolve equações. Para usá-la, primeiro especifique
++algumas variáveis; então os argumentos de ``solve`` são uma equação
++(ou um sistema de equações), juntamente com as variáveis para as
++quais resolver:
++
++::
++
++    sage: x = var('x')
++    sage: solve(x^2 + 3*x + 2, x)
++    [x == -2, x == -1]
++
++Você pode resolver equações para uma variável em termos das outras:
++
++::
++
++    sage: x, b, c = var('x b c')
++    sage: solve([x^2 + b*x + c == 0],x)
++    [x == -1/2*b - 1/2*sqrt(b^2 - 4*c), x == -1/2*b + 1/2*sqrt(b^2 - 4*c)]
++
++Você pode resolver para diversas variáveis:
++
++::
++
++    sage: x, y = var('x, y')
++    sage: solve([x+y==6, x-y==4], x, y)
++    [[x == 5, y == 1]]
++
++O seguinte exemplo, que mostra como usar o Sage para resolver um
++sistema de equações não-lineares, foi sugerido por Jason Grout:
++primeiro, resolvemos o sistemas simbolicamente:
++
++::
++
++    sage: var('x y p q')
++    (x, y, p, q)
++    sage: eq1 = p+q==9
++    sage: eq2 = q*y+p*x==-6
++    sage: eq3 = q*y^2+p*x^2==24
++    sage: solve([eq1,eq2,eq3,p==1],p,q,x,y)
++    [[p == 1, q == 8, x == -4/3*sqrt(10) - 2/3, y == 1/6*sqrt(2)*sqrt(5) - 2/3],
++     [p == 1, q == 8, x == 4/3*sqrt(10) - 2/3, y == -1/6*sqrt(2)*sqrt(5) - 2/3]]
++
++Para obter soluções numéricas aproximadas, podemos usar:
++
++.. link
++
++::
++
++    sage: solns = solve([eq1,eq2,eq3,p==1],p,q,x,y, solution_dict=True)
++    sage: [[s[p].n(30), s[q].n(30), s[x].n(30), s[y].n(30)] for s in solns]
++    [[1.0000000, 8.0000000, -4.8830369, -0.13962039],
++     [1.0000000, 8.0000000, 3.5497035, -1.1937129]]
++
++(A função ``n`` imprime uma aproximação numérica, e o argumento é o
++número de bits de precisão.)
++
++Resolvendo Equações Numericamente
++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++
++Frequentemente, ``solve`` não será capaz de encontrar uma solução
++exata para uma equação ou sistema de equações. Nesse caso, você pode
++usar ``find_root`` para encontrar uma solução numérica. Por exemplo,
++``solve`` não encontra uma solução para a equação abaixo::
++
++    sage: theta = var('theta')
++    sage: solve(cos(theta)==sin(theta), theta)
++    [sin(theta) == cos(theta)]
++
++Por outro lado, podemos usar ``find_root`` para encontrar uma solução
++para a equação acima no intervalo :math:`0 < \phi < \pi/2`::
++
++    sage: phi = var('phi')
++    sage: find_root(cos(phi)==sin(phi),0,pi/2)
++    0.785398163397448...
++
++Diferenciação, Integração, etc.
++-------------------------------
++
++O Sage é capaz de diferenciar e integrar diversas funções. Por
++exemplo, para diferenciar :math:`\sin(u)` com respeito a :math:`u`,
++faça o seguinte:
++
++::
++
++    sage: u = var('u')
++    sage: diff(sin(u), u)
++    cos(u)
++
++Para calcular a quarta derivada de :math:`\sin(x^2)`:
++
++::
++
++    sage: diff(sin(x^2), x, 4)
++    16*x^4*sin(x^2) - 48*x^2*cos(x^2) - 12*sin(x^2)
++
++Para calcular as derivadas parciais de :math:`x^2+17y^2` com respeito
++a *x* e *y*, respectivamente:
++
++::
++
++    sage: x, y = var('x,y')
++    sage: f = x^2 + 17*y^2
++    sage: f.diff(x)
++    2*x
++    sage: f.diff(y)
++    34*y
++
++Passamos agora para integrais, tanto indefinidas como definidas. Para
++calcular :math:`\int x\sin(x^2)\, dx` e :math:`\int_0^1
++\frac{x}{x^2+1}\, dx`:
++
++::
++
++    sage: integral(x*sin(x^2), x)
++    -1/2*cos(x^2)
++    sage: integral(x/(x^2+1), x, 0, 1)
++    1/2*log(2)
++
++Para calcular a decomposição em frações parciais de
++:math:`\frac{1}{x^2-1}`:
++
++::
++
++    sage: f = 1/((1+x)*(x-1))
++    sage: f.partial_fraction(x)
++    1/2/(x - 1) - 1/2/(x + 1)
++
++.. _section-systems:
++
++Resolvendo Equações Diferenciais
++--------------------------------
++
++Você pode usar o Sage para investigar equações diferenciais
++ordinárias. Para resolver a equação :math:`x'+x-1=0`:
++
++::
++
++    sage: t = var('t')    # define a variable t
++    sage: x = function('x',t)   # define x to be a function of that variable
++    sage: DE = diff(x, t) + x - 1
++    sage: desolve(DE, [x,t])
++    (c + e^t)*e^(-t)
++
++Esse método usa a interface do Sage para o Maxima [Max]_. Logo, o
++formato dos resultados é um pouco diferente de outros cálculos
++realizados no Sage. Nesse caso, o resultado diz que a solução geral da
++equação diferencial é :math:`x(t) = e^{-t}(e^{t}+c)`.
++
++Você pode calcular a transformada de Laplace também; a transformada de
++Laplace de :math:`t^2e^t -\sin(t)` é calculada da seguinte forma:
++
++::
++
++    sage: s = var("s")
++    sage: t = var("t")
++    sage: f = t^2*exp(t) - sin(t)
++    sage: f.laplace(t,s)
++    2/(s - 1)^3 - 1/(s^2 + 1)
++
++A seguir, um exemplo mais complicado. O deslocamento, com respeito à
++posição de equilíbrio, de duas massas presas a uma parede através de
++molas, conforme a figura abaixo,
++
++::
++
++    |------\/\/\/\/\---|massa1|----\/\/\/\/\/----|massa2|
++             mola1                    mola2
++
++é modelado pelo sistema de equações diferenciais de segunda ordem
++
++.. math::
++
++    m_1 x_1'' + (k_1+k_2) x_1 - k_2 x_2 = 0
++
++    m_2 x_2''+ k_2 (x_2-x_1) = 0,
++
++
++
++onde, para :math:`i=1,2`, :math:`m_{i}` é a massa do objeto *i*,
++:math:`x_{i}` é o deslocamento com respeito à posição de equilíbrio da
++massa *i*, e :math:`k_{i}` é a constante de mola para a mola *i*.
++
++**Exemplo:** Use o Sage para resolver o problema acima com
++:math:`m_{1}=2`, :math:`m_{2}=1`, :math:`k_{1}=4`,
++:math:`k_{2}=2`, :math:`x_{1}(0)=3`, :math:`x_{1}'(0)=0`,
++:math:`x_{2}(0)=3`, :math:`x_{2}'(0)=0`.
++
++Solução: Primeiramente, calcule a transformada de Laplace da primeira
++equação (usando a notação :math:`x=x_{1}`, :math:`y=x_{2}`):
++
++::
++
++    sage: de1 = maxima("2*diff(x(t),t, 2) + 6*x(t) - 2*y(t)")
++    sage: lde1 = de1.laplace("t","s"); lde1
++    2*(-?%at('diff(x(t),t,1),t=0)+s^2*'laplace(x(t),t,s)-x(0)*s)-2*'laplace(y(t),t,s)+6*'laplace(x(t),t,s)
++
++O resultado é um pouco difícil de ler, mas diz que
++
++.. math:: -2x'(0) + 2s^2*X(s) - 2sx(0) - 2Y(s) + 6X(s) = 0
++
++
++(onde a transformada de Laplace de uma função em letra minúscula
++:math:`x(t)` é a função em letra maiúscula :math:`X(s)`). Agora,
++calcule a transformada de Laplace da segunda equação:
++
++::
++
++    sage: de2 = maxima("diff(y(t),t, 2) + 2*y(t) - 2*x(t)")
++    sage: lde2 = de2.laplace("t","s"); lde2
++    -?%at('diff(y(t),t,1),t=0)+s^2*'laplace(y(t),t,s)+2*'laplace(y(t),t,s)-2*'laplace(x(t),t,s)-y(0)*s
++
++O resultado significa que
++
++.. math:: -Y'(0) + s^2Y(s) + 2Y(s) - 2X(s) - sy(0) = 0.
++
++
++Em seguida, substitua a condição inicial para :math:`x(0)`,
++:math:`x'(0)`, :math:`y(0)`, e :math:`y'(0)`, e resolva as equações
++resultantes:
++
++::
++
++    sage: var('s X Y')
++    (s, X, Y)
++    sage: eqns = [(2*s^2+6)*X-2*Y == 6*s, -2*X +(s^2+2)*Y == 3*s]
++    sage: solve(eqns, X,Y)
++    [[X == 3*(s^3 + 3*s)/(s^4 + 5*s^2 + 4),
++      Y == 3*(s^3 + 5*s)/(s^4 + 5*s^2 + 4)]]
++
++Agora calcule a transformada de Laplace inversa para obter a resposta:
++
++::
++
++    sage: var('s t')
++    (s, t)
++    sage: inverse_laplace((3*s^3 + 9*s)/(s^4 + 5*s^2 + 4),s,t)
++    cos(2*t) + 2*cos(t)
++    sage: inverse_laplace((3*s^3 + 15*s)/(s^4 + 5*s^2 + 4),s,t)
++    -cos(2*t) + 4*cos(t)
++
++Portanto, a solução é
++
++.. math:: x_1(t) = \cos(2t) + 2\cos(t), \quad x_2(t) = 4\cos(t) - \cos(2t).
++
++
++Ela pode ser representada em um gráfico parametricamente usando os
++comandos
++
++::
++
++    sage: t = var('t')
++    sage: P = parametric_plot((cos(2*t) + 2*cos(t), 4*cos(t) - cos(2*t) ),\
++    ...   (t, 0, 2*pi), rgbcolor=hue(0.9))
++    sage: show(P)
++
++As componentes individuais podem ser representadas em gráfico usando
++
++::
++
++    sage: t = var('t')
++    sage: p1 = plot(cos(2*t) + 2*cos(t), (t,0, 2*pi), rgbcolor=hue(0.3))
++    sage: p2 = plot(4*cos(t) - cos(2*t), (t,0, 2*pi), rgbcolor=hue(0.6))
++    sage: show(p1 + p2)
++
++Leia mais sobre gráficos em :ref:`section-plot`. Veja a seção 5.5 de
++[NagleEtAl2004]_ (em inglês) para mais informações sobre equações
++diferenciais.
++
++
++Método de Euler para Sistemas de Equações Diferenciais
++------------------------------------------------------
++
++No próximo exemplo, vamos ilustrar o método de Euler para EDOs de
++primeira e segunda ordem. Primeiro, relembramos a ideia básica para
++equações de primeira ordem. Dado um problema de valor inicial da forma
++
++.. math::
++
++    y'=f(x,y), \quad y(a)=c,
++
++queremos encontrar o valor aproximado da solução em :math:`x=b` com
++:math:`b>a`.
++
++Da definição de derivada segue que
++
++.. math::  y'(x) \approx \frac{y(x+h)-y(x)}{h},
++
++
++onde :math:`h>0` é um número pequeno. Isso, juntamente com a equação
++diferencial, implica que :math:`f(x,y(x))\approx
++\frac{y(x+h)-y(x)}{h}`. Agora resolvemos para :math:`y(x+h)`:
++
++.. math::   y(x+h) \approx y(x) + h*f(x,y(x)).
++
++
++Se chamarmos :math:`h f(x,y(x))` de "termo de correção", :math:`y(x)`
++de "valor antigo de *y*", e :math:`y(x+h)` de "novo valor de *y*",
++então essa aproximação pode ser reescrita como
++
++.. math::   y_{novo} \approx y_{antigo} + h*f(x,y_{antigo}).
++
++
++Se dividirmos o intervalo de *a* até *b* em *n* partes, de modo que
++:math:`h=\frac{b-a}{n}`, então podemos construir a seguinte tabela.
++
++============== ==================   ================
++:math:`x`      :math:`y`            :math:`hf(x,y)`
++============== ==================   ================
++:math:`a`      :math:`c`            :math:`hf(a,c)`
++:math:`a+h`    :math:`c+hf(a,c)`    ...
++:math:`a+2h`   ...
++...
++:math:`b=a+nh` ???                  ...
++============== ==================   ================
++
++
++O objetivo é completar os espaços em branco na tabela, em uma linha
++por vez, até atingirmos ???, que é a aproximação para :math:`y(b)`
++usando o método de Euler.
++
++A ideia para sistemas de EDOs é semelhante.
++
++**Exemplo:** Aproxime numericamente :math:`z(t)` em :math:`t=1` usando
++4 passos do método de Euler, onde :math:`z''+tz'+z=0`, :math:`z(0)=1`,
++:math:`z'(0)=0`.
++
++Devemos reduzir a EDO de segunda ordem a um sistema de duas EDOs de
++primeira ordem (usando :math:`x=z`, :math:`y=z'`) e aplicar o método
++de Euler:
++
++::
++
++    sage: t,x,y = PolynomialRing(RealField(10),3,"txy").gens()
++    sage: f = y; g = -x - y * t
++    sage: eulers_method_2x2(f,g, 0, 1, 0, 1/4, 1)
++          t                x            h*f(t,x,y)                y       h*g(t,x,y)
++          0                1                  0.00                0           -0.25
++        1/4              1.0                -0.062            -0.25           -0.23
++        1/2             0.94                 -0.12            -0.48           -0.17
++        3/4             0.82                 -0.16            -0.66          -0.081
++          1             0.65                 -0.18            -0.74           0.022
++
++Portanto, :math:`z(1)\approx 0.65`.
++
++Podemos também representar em um gráfico os pontos :math:`(x,y)` para
++obter uma figura da solução aproximada. A função
++``eulers_method_2x2_plot`` fará isso; para usá-la, precisamos definir
++funções *f* e *g* que recebam um argumento com três coordenadas (*t*,
++*x*, *y*).
++
++::
++
++    sage: f = lambda z: z[2]        # f(t,x,y) = y
++    sage: g = lambda z: -sin(z[1])  # g(t,x,y) = -sin(x)
++    sage: P = eulers_method_2x2_plot(f,g, 0.0, 0.75, 0.0, 0.1, 1.0)
++
++A esta altura, ``P`` armazena dois gráficos: ``P[0]``, o gráfico de
++*x* versus *t*, e ``P[1]``, o gráfico de *y* versus *t*. Podemos
++visualizar os dois gráficos da seguinte forma:
++
++.. link
++
++::
++
++    sage: show(P[0] + P[1])
++
++(Para mais sobre gráficos, veja :ref:`section-plot`.)
++
++Funções Especiais
++-----------------
++
++Diversos polinômios ortogonais e funções especiais estão
++implementadas, usando tanto o PARI [GP]_ como o Maxima [Max]_. Isso
++está documentado nas seções apropriadas ("Orthogonal polynomials" and
++"Special functions", respectivamente) do manual de referência do Sage
++(em inglês).
++
++::
++
++    sage: x = polygen(QQ, 'x')
++    sage: chebyshev_U(2,x)
++    4*x^2 - 1
++    sage: bessel_I(1,1,"pari",250)
++    0.56515910399248502720769602760986330732889962162109200948029448947925564096
++    sage: bessel_I(1,1)
++    0.565159103992485
++    sage: bessel_I(2,1.1,"maxima")  # last few digits are random
++    0.16708949925104899
++
++No momento, essas funções estão disponíveis na interface do Sage
++apenas para uso numérico. Para uso simbólico, use a interface do
++Maxima diretamente, como no seguinte exemplo:
++
++::
++
++    sage: maxima.eval("f:bessel_y(v, w)")
++    'bessel_y(v,w)'
++    sage: maxima.eval("diff(f,w)")
++    '(bessel_y(v-1,w)-bessel_y(v+1,w))/2'
+diff --git a/doc/pt/tutorial/tour_assignment.rst b/doc/pt/tutorial/tour_assignment.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_assignment.rst
+@@ -0,0 +1,119 @@
++Atribuição, Igualdade, e Aritmética
++===================================
++
++Com pequenas exceções, o Sage utiliza a linguagem de programação
++Python, logo a maioria dos livros de introdução ao Python vão ajudá-lo
++a aprender Sage.
++
++O Sage usa ``=`` para atribuição, e usa ``==``, ``<=``, ``>=``, ``<``
++e ``>`` para comparação:
++
++::
++
++    sage: a = 5
++    sage: a
++    5
++    sage: 2 == 2
++    True
++    sage: 2 == 3
++    False
++    sage: 2 < 3
++    True
++    sage: a == 5
++    True
++
++O Sage fornece todas as operações matemáticas básicas:
++
++::
++
++    sage: 2**3    #  ** means exponent
++    8
++    sage: 2^3     #  ^ is a synonym for ** (unlike in Python)
++    8
++    sage: 10 % 3  #  for integer arguments, % means mod, i.e., remainder
++    1
++    sage: 10/4
++    5/2
++    sage: 10//4   #  for integer arguments, // returns the integer quotient
++    2
++    sage: 4 * (10 // 4) + 10 % 4 == 10
++    True
++    sage: 3^2*4 + 2%5
++    38
++
++O cálculo de uma expressão como ``3^2*4 + 2%5`` depende da ordem em
++que as operações são aplicadas; isso é especificado na "tabela de
++precedência" em :ref:`section-precedence`.
++
++O Sage também fornece várias funções matemáticas básicas; aqui estão
++apenas alguns exemplos:
++
++::
++
++    sage: sqrt(3.4)
++    1.84390889145858 
++    sage: sin(5.135)
++    -0.912021158525540 
++    sage: sin(pi/3)
++    1/2*sqrt(3)
++
++Como o último exemplo mostra, algumas expressões matemáticas retornam
++valores 'exatos' em vez de aproximações numéricas. Para obter uma
++aproximação numérica, use a função ``n`` ou o método ``n`` (ambos
++possuem um nome longo, ``numerical_approx``, e a função ``N`` é o
++mesma que ``n``). Essas funções aceitam o argumento opcional
++``prec``, que é o número de bits de precisão requisitado, e
++``digits``, que é o número de dígitos decimais de precisão
++requisitado; o padrão é 53 bits de precisão.
++
++::
++
++    sage: exp(2)
++    e^2
++    sage: n(exp(2))
++    7.38905609893065
++    sage: sqrt(pi).numerical_approx()
++    1.77245385090552
++    sage: sin(10).n(digits=5)
++    -0.54402
++    sage: N(sin(10),digits=10)
++    -0.5440211109 
++    sage: numerical_approx(pi, prec=200)
++    3.1415926535897932384626433832795028841971693993751058209749
++
++O Python é uma linguagem "dinâmicamente digitada" (dynamically typed),
++portanto o valor referido por cada variável possui um tipo associado a
++ele, mas uma variável pode possuir valores de qualquer tipo em
++determinado escopo:
++
++::
++
++    sage: a = 5   # a is an integer
++    sage: type(a)
++    <type 'sage.rings.integer.Integer'>
++    sage: a = 5/3  # now a is a rational number
++    sage: type(a)
++    <type 'sage.rings.rational.Rational'>
++    sage: a = 'hello'  # now a is a string
++    sage: type(a)
++    <type 'str'>
++
++A linguagem de programação C, que é "estaticamente digitada"
++(statically typed), é muito diferente; uma variável que foi declarada
++como int pode apenas armazenar um int em seu escopo.
++
++Uma potencial fonte de confusão em Python é que um inteiro literal que
++começa com zero é tratado como um número octal, isto é, um número na
++base 8.
++
++::
++
++    sage: 011
++    9
++    sage: 8 + 1
++    9
++    sage: n = 011
++    sage: n.str(8)   # string representation of n in base 8
++    '11'
++
++Isso é consistente com a linguagem de programação C.
+diff --git a/doc/pt/tutorial/tour_coercion.rst b/doc/pt/tutorial/tour_coercion.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_coercion.rst
+@@ -0,0 +1,405 @@
++.. -*- coding: utf-8 -*-
++
++.. _section-coercion:
++
++============================
++Parentes, Conversão e Coação
++============================
++
++Esta seção pode parecer mais técnica do que as anteriores, mas
++acreditamos que é importante entender o significado de parentes e
++coação de modo a usar anéis e outras estruturas algébricas no Sage de
++forma efetiva e eficiente.
++
++Note que vamos explicar algumas noções, mas não vamos mostrar aqui
++como implementá-las. Um tutorial voltado à implementação está
++disponível (em inglês) como um 
++`arquivo Sage <http://flask.sagenb.org/home/pub/82/>`_.
++
++Elementos
++---------
++
++Caso se queira implementar um anel em Python, uma primeira aproximação
++seria criar uma classe para os elementos ``X`` do anel e adicionar os
++requeridos métodos (com underscores duplos) ``__add__``, ``__sub``,
++``__mul__``, obviamente garantindo que os axiomas de anel são
++verificados.
++
++Como o Python é uma linguagem "strongly typed" (ainda que "dynamically
++typed"), poderia-se, pelo menos a princípio, esperar-se que fosse
++implementado em Python uma classe para cada anel. No final das contas,
++o Python contém um tipo ``<int>`` para os inteiros, um tipo
++``<float>`` para os reais, e assim por diante. Mas essa estratégia
++logo encontra uma limitação: Existe um número infinito de anéis, e não
++se pode implementar um número infinito de classes.
++
++Em vez disso, poderia-se criar uma hierarquia de classes projetada
++para implementar elementos de estruturas algébricas ubíquas, tais como
++grupos, anéis, anéis comutativos, corpos, álgebras, e assim por
++diante.
++
++Mas isso significa que elementos de anéis bastante diferentes podem
++ter o mesmo tipo.
++
++::
++
++    sage: P.<x,y> = GF(3)[]
++    sage: Q.<a,b> = GF(4,'z')[]
++    sage: type(x)==type(a)
++    True
++
++Por outro lado, poderia-se ter também classes diferentes em Python
++fornecendo implementações diferentes da mesma estrutura matemática
++(por exemplo, matrizes densas versus matrizes esparsas).
++
++::
++
++    sage: P.<a> = PolynomialRing(ZZ)
++    sage: Q.<b> = PolynomialRing(ZZ, sparse=True)
++    sage: R.<c> = PolynomialRing(ZZ, implementation='NTL')
++    sage: type(a); type(b); type(c)
++    <type 'sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint'>
++    <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse'>
++    <type 'sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl'>
++
++Isso apresenta dois problemas: Por um lado, se tivéssemos elementos
++que são duas instancias da mesma classe, então poderia-se esperar que
++o método ``__add__`` dessas classes permitisse somá-los; mas não
++se deseja isso, se os elementos pertencem a anéis bastante diferentes.
++Por outro lado, se possui-se elementos que pertencem a implementações
++diferentes do mesmo anel, então gostaria-se de somá-los, mas isso não
++pode ser feito diretamente se eles pertencem a classes diferentes em
++Python.
++
++A solução para esses problemas é chamada coação e será explicada a
++seguir.
++
++Todavia, é essencial que cada elemento saiba a qual pertence. Isso
++está disponível através método ``parent()``:
++
++.. link
++
++::
++
++    sage: a.parent(); b.parent(); c.parent()
++    Univariate Polynomial Ring in a over Integer Ring
++    Sparse Univariate Polynomial Ring in b over Integer Ring
++    Univariate Polynomial Ring in c over Integer Ring (using NTL)
++
++
++Parentes e Categorias
++---------------------
++
++De forma similar à hierarquia de classes em Python voltada para
++elementos de estruturas algébricas, o Sage também fornece classes para
++as estruturas algébricas que contém esses elementos. Estruturas
++contendo elementos são chamadas "estruturas parente" no Sage, e existe
++uma classe básica para elas. Paralelamente à hierarquia de noções
++matemáticas, tem-se uma hierarquia de classes, a saber, para
++conjuntos, anéis, corpos e assim por diante:
++
++::
++
++    sage: isinstance(QQ,Field)
++    True
++    sage: isinstance(QQ, Ring)
++    True
++    sage: isinstance(ZZ,Field)
++    False
++    sage: isinstance(ZZ, Ring)
++    True
++
++Em álgebra, objetos que compartilham o mesmo tipo de estruturas
++algébricas são agrupados nas assim chamadas "categorias". Logo, existe
++uma analogia aproximada entre a hierarquia de classes em Sage e a
++hierarquia de categorias. Todavia, essa analogia de classes em Python
++e categorias não deve ser enfatizada demais. No final das contas,
++categorias matemáticas também são implementadas no Sage:
++
++::
++
++    sage: Rings()
++    Category of rings
++    sage: ZZ.category()
++    Category of euclidean domains
++    sage: ZZ.category().is_subcategory(Rings())
++    True
++    sage: ZZ in Rings()
++    True
++    sage: ZZ in Fields()
++    False
++    sage: QQ in Fields()
++    True
++
++Enquanto a hierarquia de classes no Sage é centrada nos detalhes de
++implementação, a construção de categorias em Sage é mais centrada
++na estrutura matemática. É possível implementar métodos e testes
++gerais independentemente de uma implementação específica nas
++categorias.
++
++Estruturas parentes em Sage são supostamente objetos únicos em Python.
++Por exemplo, uma vez que um anel de polinômios sobre um certo anel
++base e com uma certa lista de geradores é criada, o resultado é
++arquivado:
++
++::
++
++    sage: RR['x','y'] is RR['x','y']
++    True
++
++
++Tipos versus Parentes
++---------------------
++
++O tipo ``RingElement`` não deve ser confundido com a noção matemática
++de elemento de anel; por razões práticas, as vezes um objeto é uma
++instancia de ``RingElement`` embora ele não pertence a um anel:
++
++::
++
++    sage: M = Matrix(ZZ,2,3); M
++    [0 0 0]
++    [0 0 0]
++    sage: isinstance(M, RingElement)
++    True
++
++Enquanto *parentes* são únicos, elementos iguais de um parente em Sage
++não são necessariamente idênticos. Isso contrasta com o comportamento
++do Python para alguns (embora não todos) inteiros:
++
++::
++
++    sage: int(1) is int(1) # Python int
++    True
++    sage: int(-15) is int(-15)
++    False
++    sage: 1 is 1           # Sage Integer
++    False
++
++É importante observar que elementos de anéis diferentes em geral não
++podem ser distinguidos pelos seus tipos, mas sim por seus parentes:
++
++::
++
++    sage: a = GF(2)(1)
++    sage: b = GF(5)(1)
++    sage: type(a) is type(b)
++    True
++    sage: parent(a)
++    Finite Field of size 2
++    sage: parent(b)
++    Finite Field of size 5
++
++Logo, de um ponto de vista algébrico, **o parente de um elemento é
++mais importante do que seu tipo.**
++
++Conversão versus Coação
++-----------------------
++
++Em alguns casos é possível converter um elemento de uma estrutura
++parente em um elemento de uma outra estrutura parente. Tal conversão
++pode ser tanto explícita como implícita (essa é chamada *coação*).
++
++O leitor pode conhecer as noções de *conversão de tipo* e *coação de
++tipo* como na linguagem C, por exemplo. Existem noções de *conversão*
++e *coação* em Sage também. Mas as noções em Sage são centradas em
++*parentes*, não em tipos. Então, por favor não confunda conversão de
++tipo em C com conversão em Sage!
++
++Aqui se encontra uma breve apresentação. Para uma descrição detalhada
++e informações sobre a implementação, referimos à seção sobre coação no
++manual de referência e para o `arquivo tutorial
++<http://flask.sagenb.org/home/pub/82/>`_.
++
++Existem duas possibilidades extremas com respeito à possibilidade de
++fazer aritmética com elementos de *anéis diferentes*:
++
++* Anéis diferentes são mundos diferentes, e não faz nenhum sentido
++  somar ou multiplicar elementos de anéis diferentes; mesmo ``1 +
++  1/2`` não faz sentido, pois o primeiro somando é um inteiro e o
++  segundo um racional.
++
++Ou
++
++* Se um elemento ``r1`` de uma aner ``R1`` pode de alguma forma ser
++  interpretado em um outro anel ``R2``, então todas as operações
++  aritméticas envolvendo ``r1`` e qualquer elemento de ``R2`` são
++  permitidas. O elemento neutro da multiplicação existe em todos os
++  corpos e em vários anéis, e eles devem ser todos iguais.
++
++O Sage faz uma concessão. Se ``P1`` e ``P2`` são estruturas parentes e
++``p1`` é um elemento de ``P1``, então o usuário pode explicitamente
++perguntar por uma interpretação de ``p1`` em ``P2``. Isso pode não
++fazer sentido em todos os casos ou não estar definido para todos os
++elementos de ``P1``, e fica a cargo do usuário assegurar que isso faz
++sentido. Nos referimos a isso como **conversão**:
++
++::
++
++    sage: a = GF(2)(1)
++    sage: b = GF(5)(1)
++    sage: GF(5)(a) == b
++    True
++    sage: GF(2)(b) == a
++    True
++
++Todavia, uma conversão *implícita* (ou automática) ocorrerá apenas se
++puder ser feita *completamente* e *consistentemente*. Rigor matemático
++é essencial nesse ponto.
++
++Uma tal conversão implícita é chamada **coação**. Se coação for
++definida, então deve coincidir com conversão. Duas condições devem ser
++satisfeitas para uma coação ser definida:
++
++#. Uma coação de ``P1`` para ``P2`` deve ser dada por uma estrutura
++   que preserva mapeamentos (por exemplo, um homomorfismo de anéis).
++   Não é suficiente que *alguns* elementos de ``P1`` possam ser
++   mapeados em ``P2``, e o mapa deve respeitar a estrutura algébrica
++   de ``P1``.
++#. A escolha desses mapas de coação deve ser consistente: Se ``P3`` é
++   uma terceira estrutura parente, então a composição da coação
++   adotada de ``P1`` para ``P2`` com a coação de ``P2`` para ``P3``
++   deve coincidir com a coação adotada de ``P1`` para ``P3``. Em
++   particular, se existir uma coação de ``P1`` para ``P2`` e ``P2``
++   para ``P1``, a composição deve ser o mapa identidade em ``P1``.
++
++Logo, embora é possível converter cada elemento de ``GF(2)`` para
++``GF(5)``, não há coação, pois não existe homomorfismo de anel entre
++``GF(2)`` e ``GF(5)``.
++
++O segundo aspecto - consistência - é um pouco mais difícil de
++explicar. Vamos ilustrá-lo usando anéis de polinômios em mais de uma
++variável. Em aplicações, certamente faz mais sentido ter coações que
++preservam nomes. Então temos:
++
++::
++
++    sage: R1.<x,y> = ZZ[]
++    sage: R2 = ZZ['y','x']
++    sage: R2.has_coerce_map_from(R1)
++    True
++    sage: R2(x)
++    x
++    sage: R2(y)
++    y
++
++Se não existir homomorfismo de anel que preserve nomes, coerção não é
++definida. Todavia, conversão pode ainda ser possível, a saber,
++mapeando geradores de anel de acordo com sua posição da lista de
++geradores:
++
++.. link
++
++::
++
++    sage: R3 = ZZ['z','x']
++    sage: R3.has_coerce_map_from(R1)
++    False
++    sage: R3(x)
++    z
++    sage: R3(y)
++    x
++
++Mas essas conversões que preservam a posição não se qualificam como
++coação: Compondo um mapa que preserva nomes de ``ZZ['x','y']`` para
++``ZZ['y','x']``, com um mapa que preserva nomes de ``ZZ['y','x']``
++para ``ZZ['a','b']``, resultaria em um mapa que não preserva nomes nem
++posição, violando a consistência.
++
++Se houver coação, ela será usada para comparar elementos de anéis
++diferentes ou fazer aritmética. Isso é frequentemente conveniente, mas
++o usuário deve estar ciente que estender a relação ``==`` além das
++fronteiras de parentes diferentes pode facilmente resultar em 
++problemas. Por exemplo, enquanto ``==`` é supostamente uma relação de
++equivalência sobre os elementos de *um* anel, isso não é
++necessariamente o caso se anéis *diferentes* estão envolvidos. Por
++exemplo, ``1`` em ``ZZ`` e em um corpo finito são considerados iguais,
++pois existe uma coação canônica dos inteiros em qualquer corpo finito.
++Todavia, em geral não existe coação entre dois corpos finitos
++diferentes. Portanto temos
++
++.. link
++
++::
++
++    sage: GF(5)(1) == 1
++    True
++    sage: 1 == GF(2)(1)
++    True
++    sage: GF(5)(1) == GF(2)(1)
++    False
++    sage: GF(5)(1) != GF(2)(1)
++    True
++
++Similarmente,
++
++.. link
++
++::
++
++    sage: R3(R1.1) == R3.1
++    True
++    sage: R1.1 == R3.1
++    False
++    sage: R1.1 != R3.1
++    True
++
++Uma outra consequência da condição de consistência é que coação pode
++apenas ir de anéis exatos (por exemplo, os racionais ``QQ``) para
++anéis não-exatos (por exemplo, os números reais com uma precisão fixa
++``RR``), mas não na outra direção. A razão é que a composição da
++coação de ``QQ`` em ``RR`` com a conversão de ``RR`` para ``QQ``
++deveria ser a identidade em ``QQ``. Mas isso é impossível, pois alguns
++números racionais distintos podem ser tratados como iguais em ``RR``,
++como no seguinte exemplo:
++
++::
++
++    sage: RR(1/10^200+1/10^100) == RR(1/10^100)
++    True
++    sage: 1/10^200+1/10^100 == 1/10^100
++    False
++
++Quando se compara elementos de dois parentes ``P1`` e ``P2``, é
++possível que não haja coação entre os dois anéis, mas existe uma
++escolha canônica de um parente ``P3`` de modo que tanto ``P1`` como
++``P2`` são coagidos em ``P3``. Nesse caso, coação vai ocorrer também.
++Um caso de uso típico é na soma de um número racional com um polinômio
++com coeficientes inteiros, resultando em um polinômio com coeficientes
++racionais:
++
++::
++
++    sage: P1.<x> = ZZ[]
++    sage: p = 2*x+3
++    sage: q = 1/2
++    sage: parent(p)
++    Univariate Polynomial Ring in x over Integer Ring
++    sage: parent(p+q)
++    Univariate Polynomial Ring in x over Rational Field
++
++Note que a princípio o resultado deveria também fazer sentido no
++corpo de frações de ``ZZ['x']``. Todavia, o Sage tenta escolher um
++parente *canônico* comum que parece ser o mais natural (``QQ['x']`` no
++nosso exemplo). Se vários potenciais parentes comuns parecem
++igualmente naturais, o Sage *não* vai escolher um deles
++aleatoriamente. Os mecanismos sobre os quais essa escolha se baseia é
++explicado em um `arquivo tutorial
++<http://flask.sagenb.org/home/pub/82/>`_
++
++Nenhuma coação para um parente comum vai ocorrer no seguinte exemplo:
++
++::
++
++    sage: R.<x> = QQ[]
++    sage: S.<y> = QQ[]
++    sage: x+y
++    Traceback (most recent call last):
++    ...
++    TypeError: unsupported operand parent(s) for '+': 'Univariate Polynomial Ring in x over Rational Field' and 'Univariate Polynomial Ring in y over Rational Field'
++
++A razão é que o Sage não escolhe um dos potenciais candidatos
++``QQ['x']['y']``, ``QQ['y']['x']``, ``QQ['x','y']`` ou
++``QQ['y','x']``, porque todas essas estruturas combinadas em pares
++diferentes parecem ser parentes comuns naturais, e não existe escolha
++canônica aparente.
+diff --git a/doc/pt/tutorial/tour_functions.rst b/doc/pt/tutorial/tour_functions.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_functions.rst
+@@ -0,0 +1,236 @@
++.. _section-functions-issues:
++
++Algumas Questões Frequentes sobre Funções
++=========================================
++
++Alguns aspectos sobre definição de funções (por exemplo, para
++diferenciação, ou para criar gráficos) podem se tornar confusos. Nesta
++seção, procuramos tratar algumas questões relevantes.
++
++Aqui estão várias formas de definir objetos que merecem ser chamamos
++de "funções":
++
++1. Defina uma função em Python, como descrito em
++:ref:`section-functions`. Essas funções podem ser usadas para criar
++gráficos, mas não podem ser diferenciadas ou integradas.
++
++::
++
++       sage: def f(z): return z^2
++       sage: type(f)
++       <type 'function'>
++       sage: f(3)
++       9
++       sage: plot(f, 0, 2)
++
++Na última linha, observe a sintaxe. Se fosse usado ``plot(f(z), 0,
++2)`` ocorreria um erro, porque ``z`` é uma variável muda na definição
++de ``f`` e não está definida fora do contexto da função. De fato,
++somente ``f(z)`` já provoca um erro. Os seguintes comandos vão
++funcionar neste caso, embora em geral eles devam ser evitados pois
++podem ocasionar erros (veja o item 4 abaixo).
++
++.. link
++
++::
++
++       sage: var('z')   # define z to be a variable
++       z
++       sage: f(z)
++       z^2
++       sage: plot(f(z), 0, 2)
++
++Acima, ``f(z)`` é uma expressão simbólica, o próximo item na nossa
++lista.
++
++2. Defina um "expressão simbólica que pode ser evocada". Essas podem
++ser usadas para criar gráficos, e podem ser diferenciadas ou
++integradas.
++
++::
++
++       sage: g(x) = x^2
++       sage: g        # g sends x to x^2
++       x |--> x^2
++       sage: g(3)
++       9
++       sage: Dg = g.derivative(); Dg
++       x |--> 2*x
++       sage: Dg(3)
++       6
++       sage: type(g)
++       <type 'sage.symbolic.expression.Expression'>
++       sage: plot(g, 0, 2)
++
++Note que enquanto ``g`` é uma expressão simbólica que pode ser
++evocada, ``g(x)`` é um objeto diferente, embora relacionado, que pode
++ser usado para criar gráficos, ou ser diferenciado, integrado, etc.,
++embora com algumas ressalvas: veja o item 5 abaixo.
++
++.. link
++
++::
++
++       sage: g(x)
++       x^2
++       sage: type(g(x))
++       <type 'sage.symbolic.expression.Expression'>
++       sage: g(x).derivative()
++       2*x
++       sage: plot(g(x), 0, 2)
++
++3. Use uma função pré-definida. Essas podem ser representadas em
++gráfico, e com uma pequena ajuda, diferenciadas e integradas.
++
++::
++
++       sage: type(sin)
++       <class 'sage.functions.trig.Function_sin'>
++       sage: plot(sin, 0, 2)
++       sage: type(sin(x))
++       <type 'sage.symbolic.expression.Expression'>
++       sage: plot(sin(x), 0, 2)
++       
++Por si só, ``sin`` não pode ser diferenciado, pelo menos não para
++produzir ``cos``.
++
++::
++
++       sage: f = sin	
++       sage: f.derivative()
++       Traceback (most recent call last):
++       ...
++       AttributeError: ...
++
++Usando ``f = sin(x)`` no lugar de ``sin`` funciona, mas é ainda melhor
++usar ``f(x) = sin(x)`` para definir uma expressão simbólica que pode
++ser evocada.
++
++::
++   
++       sage: S(x) = sin(x)
++       sage: S.derivative()
++       x |--> cos(x)
++       
++Aqui estão alguns problemas comuns, com explicações:
++
++\4. Cálculo acidental.
++
++::
++
++       sage: def h(x):
++       ...       if x<2:
++       ...	     return 0
++       ...       else:
++       ...	     return x-2
++
++O problema: ``plot(h(x), 0, 4)`` cria o gráfico da reta `y=x-2`, não
++da função definida por ``h``. O motivo? No comando ``plot(h(x), 0,
++4)``, primeiro ``h(x)`` é calculada: isso significa substituir ``x``
++na função ``h``, o que significa que ``x<2`` é calculado.
++
++.. link
++
++::
++
++       sage: type(x<2)
++       <type 'sage.symbolic.expression.Expression'>
++
++Quando uma equação simbólica é calculada, como na definição de ``h``,
++se ela não é obviamente verdadeira, então ela retorna False. Logo
++``h(x)`` é calculada como ``x-2``, e essa é a função que será
++representada no gráfico.
++
++A solução: não use ``plot(h(x), 0, 4)``; em vez disso, use
++
++.. link
++
++::
++
++       sage: plot(h, 0, 4)
++
++\5. Acidentalmente produzindo uma constante em vez de uma função.
++
++::
++
++       sage: f = x
++       sage: g = f.derivative() 
++       sage: g
++       1
++
++O problema: ``g(3)``, por exemplo, retorna o erro "ValueError: the
++number of arguments must be less than or equal to 0."
++
++.. link
++
++::
++
++       sage: type(f)
++       <type 'sage.symbolic.expression.Expression'>
++       sage: type(g)
++       <type 'sage.symbolic.expression.Expression'>
++       
++``g`` não é uma função, é uma constante, logo não possui variáveis
++associadas, e você não pode substituir nenhum valor em ``g``.
++
++Solução: existem vária opções.
++
++- Defina ``f`` inicialmente como uma expressão simbólica.
++
++::
++
++         sage: f(x) = x        # instead of 'f = x'
++         sage: g = f.derivative()
++         sage: g
++         x |--> 1
++         sage: g(3)
++         1
++         sage: type(g)
++         <type 'sage.symbolic.expression.Expression'>
++
++- Ou com ``f`` como definida originalmente, defina ``g`` como uma
++  expressão simbólica.
++
++::
++
++         sage: f = x
++         sage: g(x) = f.derivative()  # instead of 'g = f.derivative()'
++         sage: g
++         x |--> 1
++         sage: g(3)
++         1
++         sage: type(g)
++         <type 'sage.symbolic.expression.Expression'>
++
++- Ou com ``f`` e ``g`` como definidas originalmente, especifique a
++  variável para a qual você está substituindo.
++
++::
++
++         sage: f = x
++         sage: g = f.derivative()
++         sage: g
++         1
++         sage: g(x=3)    # instead of 'g(3)'
++         1
++
++Finalmente, aqui vai mais uma forma de saber a diferença entre as
++derivadas de ``f = x`` e ``f(x) = x``.
++
++::
++
++       sage: f(x) = x 
++       sage: g = f.derivative()
++       sage: g.variables()  # the variables present in g
++       ()
++       sage: g.arguments()  # the arguments which can be plugged into g
++       (x,)
++       sage: f = x
++       sage: h = f.derivative()
++       sage: h.variables()
++       ()
++       sage: h.arguments()
++       ()
++       
++Como esse exemplo procura ilustrar, ``h`` não aceita argumentos, e é
++por isso que ``h(3)`` retorna um erro.
+diff --git a/doc/pt/tutorial/tour_groups.rst b/doc/pt/tutorial/tour_groups.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_groups.rst
+@@ -0,0 +1,92 @@
++Grupos Finitos, Grupos Abelianos
++================================
++
++O Sage possui suporte para fazer cálculos com grupos de permutação,
++grupos finitos clássicos (tais como :math:`SU(n,q)`), grupos
++matriciais finitos (com os seus próprios geradores), e grupos
++abelianos (até mesmo infinitos). A maior parte disso é implementada
++usando a interface com o GAP.
++
++Por exemplo, para criar um grupo de permutação, forneça uma lista de
++geradores, como no seguinte exemplo.
++
++::
++
++    sage: G = PermutationGroup(['(1,2,3)(4,5)', '(3,4)'])
++    sage: G
++    Permutation Group with generators [(3,4), (1,2,3)(4,5)]
++    sage: G.order()
++    120
++    sage: G.is_abelian()
++    False
++    sage: G.derived_series()           # random-ish output
++    [Permutation Group with generators [(1,2,3)(4,5), (3,4)],
++     Permutation Group with generators [(1,5)(3,4), (1,5)(2,4), (1,3,5)]]
++    sage: G.center()
++    Subgroup of (Permutation Group with generators [(3,4), (1,2,3)(4,5)]) generated by [()]
++    sage: G.random_element()           # random output
++    (1,5,3)(2,4)
++    sage: print latex(G)
++    \langle (3,4), (1,2,3)(4,5) \rangle
++
++Você pode também obter a tabela de caracteres (em formato LaTeX) no
++Sage:
++
++::
++
++    sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3)]])
++    sage: latex(G.character_table())
++    \left(\begin{array}{rrrr}
++    1 & 1 & 1 & 1 \\
++    1 & 1 & -\zeta_{3} - 1 & \zeta_{3} \\
++    1 & 1 & \zeta_{3} & -\zeta_{3} - 1 \\
++    3 & -1 & 0 & 0
++    \end{array}\right)
++
++O Sage também inclui grupos clássicos matriciais sobre corpos finitos:
++
++::
++
++    sage: MS = MatrixSpace(GF(7), 2)
++    sage: gens = [MS([[1,0],[-1,1]]),MS([[1,1],[0,1]])]
++    sage: G = MatrixGroup(gens)
++    sage: G.conjugacy_class_representatives()
++        [
++        [1 0]
++        [0 1],
++        [0 1]
++        [6 1],
++        ...
++        [6 0]
++        [0 6]
++        ]
++    sage: G = Sp(4,GF(7))
++    sage: G._gap_init_()
++    'Sp(4, 7)'
++    sage: G
++    Symplectic Group of rank 2 over Finite Field of size 7
++    sage: G.random_element()             # random output
++    [5 5 5 1]
++    [0 2 6 3]
++    [5 0 1 0]
++    [4 6 3 4]
++    sage: G.order()
++    276595200
++
++Você também pode fazer cálculos usando grupos abelianos (finitos ou
++infinitos):
++
++::
++
++    sage: F = AbelianGroup(5, [5,5,7,8,9], names='abcde')
++    sage: (a, b, c, d, e) = F.gens()
++    sage: d * b**2 * c**3 
++    b^2*c^3*d
++    sage: F = AbelianGroup(3,[2]*3); F
++    Multiplicative Abelian Group isomorphic to C2 x C2 x C2
++    sage: H = AbelianGroup([2,3], names="xy"); H
++    Multiplicative Abelian Group isomorphic to C2 x C3
++    sage: AbelianGroup(5)
++    Multiplicative Abelian Group isomorphic to Z x Z x Z x Z x Z
++    sage: AbelianGroup(5).order()
++    +Infinity
+diff --git a/doc/pt/tutorial/tour_help.rst b/doc/pt/tutorial/tour_help.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_help.rst
+@@ -0,0 +1,363 @@
++.. _chapter-help:
++
++Obtendo ajuda
++=============
++
++O Sage possui vasta documentação, acessível digitando o nome de uma
++função ou constante (por exemplo), seguido pelo ponto de interrogação:
++
++.. skip
++
++::
++
++    sage: tan?
++    Type:        <class 'sage.calculus.calculus.Function_tan'>
++    Definition:  tan( [noargspec] )
++    Docstring: 
++    
++        The tangent function
++    
++        EXAMPLES:
++            sage: tan(pi)
++            0
++            sage: tan(3.1415)
++            -0.0000926535900581913
++            sage: tan(3.1415/4)
++            0.999953674278156
++            sage: tan(pi/4)
++            1
++            sage: tan(1/2)
++            tan(1/2)
++            sage: RR(tan(1/2))
++            0.546302489843790
++    sage: log2?
++    Type:        <class 'sage.functions.constants.Log2'>
++    Definition:  log2( [noargspec] )
++    Docstring: 
++    
++        The natural logarithm of the real number 2.
++        
++        EXAMPLES:
++            sage: log2
++            log2
++            sage: float(log2)
++            0.69314718055994529
++            sage: RR(log2)
++            0.693147180559945
++            sage: R = RealField(200); R
++            Real Field with 200 bits of precision
++            sage: R(log2)
++            0.69314718055994530941723212145817656807550013436025525412068
++            sage: l = (1-log2)/(1+log2); l
++            (1 - log(2))/(log(2) + 1)
++            sage: R(l)
++            0.18123221829928249948761381864650311423330609774776013488056
++            sage: maxima(log2)
++            log(2)
++            sage: maxima(log2).float()
++            .6931471805599453
++            sage: gp(log2)
++            0.6931471805599453094172321215             # 32-bit
++            0.69314718055994530941723212145817656807   # 64-bit
++    sage: sudoku?
++    File:        sage/local/lib/python2.5/site-packages/sage/games/sudoku.py
++    Type:        <type 'function'>
++    Definition:  sudoku(A)
++    Docstring: 
++    
++        Solve the 9x9 Sudoku puzzle defined by the matrix A.
++    
++        EXAMPLE:
++            sage: A = matrix(ZZ,9,[5,0,0, 0,8,0, 0,4,9, 0,0,0, 5,0,0,
++        0,3,0, 0,6,7, 3,0,0, 0,0,1, 1,5,0, 0,0,0, 0,0,0, 0,0,0, 2,0,8, 0,0,0,
++        0,0,0, 0,0,0, 0,1,8, 7,0,0, 0,0,4, 1,5,0,   0,3,0, 0,0,2,
++        0,0,0, 4,9,0, 0,5,0, 0,0,3])
++            sage: A
++            [5 0 0 0 8 0 0 4 9]
++            [0 0 0 5 0 0 0 3 0]
++            [0 6 7 3 0 0 0 0 1]
++            [1 5 0 0 0 0 0 0 0]
++            [0 0 0 2 0 8 0 0 0]
++            [0 0 0 0 0 0 0 1 8]
++            [7 0 0 0 0 4 1 5 0]
++            [0 3 0 0 0 2 0 0 0]
++            [4 9 0 0 5 0 0 0 3]
++            sage: sudoku(A)
++            [5 1 3 6 8 7 2 4 9]
++            [8 4 9 5 2 1 6 3 7]
++            [2 6 7 3 4 9 5 8 1]
++            [1 5 8 4 6 3 9 7 2]
++            [9 7 4 2 1 8 3 6 5]
++            [3 2 6 7 9 5 4 1 8]
++            [7 8 2 9 3 4 1 5 6]
++            [6 3 5 1 7 2 8 9 4]
++            [4 9 1 8 5 6 7 2 3]
++
++O Sage também fornece completamento tab: digite as primeiras letras de
++uma função e então pressione a tecla tab. Por exemplo, se você digitar
++``ta`` seguido de ``TAB``, o Sage vai imprimir ``tachyon, tan, tanh,
++taylor``. Essa é uma boa forma de encontrar nomes de funções e outras
++estruturas no Sage.
++
++
++.. _section-functions:
++
++Funções, Tabulação, e Contagem
++===============================
++
++Para definir uma nova função no Sage, use o comando ``def`` e dois
++pontos após a lista de nomes das variáveis. Por exemplo:
++
++::
++
++    sage: def is_even(n):
++    ...       return n%2 == 0
++    ...
++    sage: is_even(2)
++    True
++    sage: is_even(3)
++    False
++
++Observação: Dependendo da versão do tutorial que você está lendo,
++você pode ver três pontos ``...`` na segunda linha desse exemplo. Não
++digite esses pontos; eles são apenas para enfatizar que o código está
++tabulado. Se for esse o caso, pressione [Enter] uma vez após o fim do
++bloco de código para inserir uma linha em branco e concluir a
++definição da função.
++
++Você não especifica o tipo de dado de nenhum dos argumentos da função.
++É possível especificar argumentos múltiplos, cada um dos quais pode
++ter um valor opcional padrão. Por exemplo, a função abaixo usa o valor
++padrão ``divisor=2`` se ``divisor`` não é especificado.
++
++::
++
++    sage: def is_divisible_by(number, divisor=2):
++    ...       return number%divisor == 0
++    sage: is_divisible_by(6,2)
++    True
++    sage: is_divisible_by(6)
++    True
++    sage: is_divisible_by(6, 5)
++    False
++
++Você também pode especificar explicitamente um ou mais argumentos
++quando evocar uma função; se você especificar os argumentos
++explicitamente, você pode fazê-lo em qualquer ordem:
++
++.. link
++
++::
++
++    sage: is_divisible_by(6, divisor=5)
++    False
++    sage: is_divisible_by(divisor=2, number=6)
++    True
++
++Em Python, blocos de código não são indicados por colchetes ou blocos
++de início e fim, como em outras linguagens. Em vez disso, blocos de
++código são indicados por tabulação, que devem estar alinhadas
++exatamente. Por exemplo, o seguinte código possui um erro de sintaxe
++porque o comando ``return`` não possui a mesma tabulação da linha que
++inicia o seu bloco de código.
++
++.. skip
++
++::
++
++    sage: def even(n):
++    ...       v = []
++    ...       for i in range(3,n):
++    ...           if i % 2 == 0:
++    ...               v.append(i)
++    ...      return v
++    Syntax Error:
++           return v
++
++Se você corrigir a tabulação, a função fica correta:
++
++::
++
++    sage: def even(n):
++    ...       v = []
++    ...       for i in range(3,n):
++    ...           if i % 2 == 0:
++    ...               v.append(i)
++    ...       return v
++    sage: even(10)
++    [4, 6, 8]
++
++Não é necessário inserir ponto-e-vírgula no final da linha. Todavia,
++você pode inserir múltiplos comandos em uma mesma linha separados por
++ponto-e-vírgula:
++
++::
++
++    sage: a = 5; b = a + 3; c = b^2; c
++    64
++
++Se você quiser que uma única linha de comando seja escrita em mais de
++uma linha, use a barra invertida para quebrar a linha:
++
++::
++
++    sage: 2 + \
++    ...      3
++    5
++
++Em Sage, a contagem é feita iterando sobre um intervalo de inteiros.
++Por exemplo, a primeira linha abaixo é equivalente a ``for(i=0; i<3;
++i++)`` em C++ ou Java:
++
++::
++
++    sage: for i in range(3):
++    ...       print i
++    0
++    1
++    2
++
++A primeira linha abaixo é equivalente a ``for(i=2; i<5; i++)``.
++
++::
++
++    sage: for i in range(2,5):
++    ...       print i
++    2
++    3
++    4
++
++O Terceiro argumento controla o passo. O comando abaixo é equivalente
++a ``for(i=1; i<6; i+=2)``.
++
++::
++
++    sage: for i in range(1,6,2):
++    ...       print i
++    1
++    3
++    5
++
++Frequentemente deseja-se criar uma tabela para visualizar resultados
++calculados com o Sage. Uma forma fácil de fazer isso é utilizando
++formatação de strings. Abaixo, criamos três colunas cada uma com
++largura exatamente 6, e fazemos uma tabela com quadrados e cubos de
++alguns números.
++
++::
++
++    sage: for i in range(5):
++    ...       print '%6s %6s %6s'%(i, i^2, i^3)
++         0      0      0
++         1      1      1
++         2      4      8
++         3      9     27
++         4     16     64
++
++A estrutura de dados mais básica em Sage é a lista, que é -- como o
++nome sugere -- simplesmente uma lista de objetos arbitrários. Por
++exemplo, o comando ``range`` que usamos acima cria uma lista:
++
++::
++
++    sage: range(2,10)
++    [2, 3, 4, 5, 6, 7, 8, 9]
++
++Abaixo segue uma lista mais complicada:
++
++::
++
++    sage: v = [1, "hello", 2/3, sin(x^3)]
++    sage: v
++    [1, 'hello', 2/3, sin(x^3)]
++
++Listas são indexadas começando do 0, como em várias linguagens de
++programação.
++
++.. link
++
++::
++
++    sage: v[0]
++    1
++    sage: v[3]
++    sin(x^3)
++
++Use ``len(v)`` para obter o comprimento de ``v``, use
++``v.append(obj)`` para inserir um novo objeto no final de ``v``, e use
++``del v[i]`` para remover o :math:`i`-ésimo elemento de ``v``:
++
++.. link
++
++::
++
++    sage: len(v)
++    4
++    sage: v.append(1.5)
++    sage: v
++    [1, 'hello', 2/3, sin(x^3), 1.50000000000000]
++    sage: del v[1]
++    sage: v
++    [1, 2/3, sin(x^3), 1.50000000000000]
++
++Outra importante estrutura de dados é o dicionário (ou lista
++associativa). Ele funciona como uma lista, exceto que pode ser
++indexado por vários tipos de objeto (os índices devem ser imutáveis):
++
++::
++
++    sage: d = {'hi':-2,  3/8:pi,   e:pi}
++    sage: d['hi']
++    -2
++    sage: d[e]
++    pi
++
++Você pode também definir novos tipos de dados usando classes.
++Encapsular objetos matemáticos usando classes é uma técnica poderosa
++que pode ajudar a simplificar e organizar os seus programas em Sage.
++Abaixo, definimos uma nova classe que representa a lista de inteiros
++pares positivos até *n*; essa classe é derivada do tipo ``list``.
++
++::
++
++    sage: class Evens(list):
++    ...       def __init__(self, n):
++    ...           self.n = n
++    ...           list.__init__(self, range(2, n+1, 2))
++    ...       def __repr__(self):
++    ...           return "Even positive numbers up to n."
++
++O método ``__init__`` é evocado para inicializar o objeto quando ele é
++criado; o método ``__repr__`` imprime o objeto. Nós evocamos o
++construtor ``__init__`` do tipo ``list`` na segunda linha do método
++``__init__``. Criamos um objeto da classe ``Evens`` da seguinte forma:
++
++.. link
++
++::
++
++    sage: e = Evens(10)
++    sage: e
++    Even positive numbers up to n.
++
++Note que ``e`` imprime usando o método ``__repr__`` que nós
++definimos. Para ver a lista de números, use a função ``list``:
++
++.. link
++
++::
++
++    sage: list(e)
++    [2, 4, 6, 8, 10]
++
++Podemos também acessar o atributo ``n`` ou tratar ``e`` como uma
++lista.
++
++.. link
++
++::
++
++    sage: e.n
++    10
++    sage: e[2]
++    6
+diff --git a/doc/pt/tutorial/tour_linalg.rst b/doc/pt/tutorial/tour_linalg.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_linalg.rst
+@@ -0,0 +1,233 @@
++.. _section-linalg:
++
++Álgebra Linear
++==============
++
++O Sage fornece os objetos usuais em álgebra linear, por exemplo, o
++polinômio característico, matriz escalonada, traço, decomposição,
++etc., de uma matriz.
++
++Criar e multiplicar matrizes é fácil e natural:
++
++::
++
++    sage: A = Matrix([[1,2,3],[3,2,1],[1,1,1]])
++    sage: w = vector([1,1,-4])
++    sage: w*A
++    (0, 0, 0)
++    sage: A*w
++    (-9, 1, -2)
++    sage: kernel(A)
++    Free module of degree 3 and rank 1 over Integer Ring
++    Echelon basis matrix:
++    [ 1  1 -4]
++
++Note que no Sage, o núcleo de uma matriz :math:`A` é o núcleo à
++esquerda, i.e., o conjunto de vetores :math:`w` tal que :math:`wA=0`.
++
++Resolver equações matriciais é fácil usando o método ``solve_right``.
++Calculando ``A.solve_right(Y)`` obtém-se uma matrix (ou vetor)
++:math:`X` tal que :math:`AX=Y`:
++
++.. link
++
++::
++
++    sage: Y = vector([0, -4, -1])
++    sage: X = A.solve_right(Y)
++    sage: X
++    (-2, 1, 0)
++    sage: A * X   # checking our answer...
++    (0, -4, -1)
++
++Uma barra invertida ``\`` pode ser usada no lugar de ``solve_right``;
++use ``A \ Y`` no lugar de ``A.solve_right(Y)``.
++
++.. link
++
++::
++
++    sage: A \ Y
++    (-2, 1, 0)
++
++Se não existir solução, o Sage retorna um erro:
++
++.. skip
++
++::
++
++    sage: A.solve_right(w)
++    Traceback (most recent call last):
++    ...
++    ValueError: matrix equation has no solutions
++
++Similarmente, use ``A.solve_left(Y)`` para resolver para :math:`X` em
++:math:`XA=Y`.
++
++O Sage também pode calcular autovalores e autovetores::
++
++    sage: A = matrix([[0, 4], [-1, 0]])
++    sage: A.eigenvalues ()
++    [-2*I, 2*I]
++    sage: B = matrix([[1, 3], [3, 1]])
++    sage: B.eigenvectors_left()
++    [(4, [
++    (1, 1)
++    ], 1), (-2, [
++    (1, -1)
++    ], 1)]
++
++(A sintaxe para a resposta de ``eigenvectors_left`` é uma lista com
++três componentes: (autovalor, autovetor, multiplicidade).) Autovalores
++e autovetores sobre ``QQ`` ou ``RR`` também podem ser calculados
++usando o Maxima (veja :ref:`section-maxima`).
++
++Como observado em :ref:`section-rings`, o anel sobre o qual a matriz
++esta definida afeta alguma de suas propriedades. A seguir, o primeiro
++argumento do comando ``matrix`` diz para o Sage considerar a matriz
++como uma matriz de inteiros (o caso ``ZZ``), uma matriz de números
++racionais (``QQ``), ou uma matriz de números reais (``RR``)::
++
++    sage: AZ = matrix(ZZ, [[2,0], [0,1]])
++    sage: AQ = matrix(QQ, [[2,0], [0,1]])
++    sage: AR = matrix(RR, [[2,0], [0,1]])
++    sage: AZ.echelon_form()
++    [2 0]
++    [0 1]
++    sage: AQ.echelon_form()
++    [1 0]
++    [0 1]
++    sage: AR.echelon_form()
++    [ 1.00000000000000 0.000000000000000]
++    [0.000000000000000  1.00000000000000]
++
++Espaços de Matrizes
++-------------------
++
++Agora criamos o espaço :math:`\text{Mat}_{3\times 3}(\QQ)` de matrizes
++`3 \times 3` com entradas racionais::
++
++    sage: M = MatrixSpace(QQ,3)
++    sage: M
++    Full MatrixSpace of 3 by 3 dense matrices over Rational Field
++
++(Para especificar o espaço de matrizes 3 por 4, você usaria
++``MatrixSpace(QQ,3,4)``. Se o número de colunas é omitido, ele é
++considerado como igual ao número de linhas, portanto,
++``MatrixSpace(QQ,3)`` é sinônimo de ``MatrixSpace(QQ,3,3)``.) O espaço
++de matrizes possui uma base que o Sage armazena como uma lista:
++
++.. link
++
++::
++
++    sage: B = M.basis()
++    sage: len(B)
++    9
++    sage: B[1]
++    [0 1 0]
++    [0 0 0]
++    [0 0 0]
++
++Vamos criar uma matriz como um elemento de ``M``.
++
++.. link
++
++::
++
++    sage: A = M(range(9)); A
++    [0 1 2]
++    [3 4 5]
++    [6 7 8]
++
++A seguir calculamos a sua forma escalonada e o núcleo.
++
++.. link
++
++::
++
++    sage: A.echelon_form()
++    [ 1  0 -1]
++    [ 0  1  2]
++    [ 0  0  0]
++    sage: A.kernel()
++    Vector space of degree 3 and dimension 1 over Rational Field
++    Basis matrix:
++    [ 1 -2  1]
++
++Agora ilustramos o cálculo com matrizes definidas sobre um corpo
++finito:
++
++::
++
++    sage: M = MatrixSpace(GF(2),4,8)
++    sage: A = M([1,1,0,0, 1,1,1,1, 0,1,0,0, 1,0,1,1, 
++    ...          0,0,1,0, 1,1,0,1, 0,0,1,1, 1,1,1,0])
++    sage: A
++    [1 1 0 0 1 1 1 1]
++    [0 1 0 0 1 0 1 1]
++    [0 0 1 0 1 1 0 1]
++    [0 0 1 1 1 1 1 0]
++    sage: rows = A.rows()
++    sage: A.columns()
++    [(1, 0, 0, 0), (1, 1, 0, 0), (0, 0, 1, 1), (0, 0, 0, 1), 
++     (1, 1, 1, 1), (1, 0, 1, 1), (1, 1, 0, 1), (1, 1, 1, 0)]
++    sage: rows
++    [(1, 1, 0, 0, 1, 1, 1, 1), (0, 1, 0, 0, 1, 0, 1, 1), 
++     (0, 0, 1, 0, 1, 1, 0, 1), (0, 0, 1, 1, 1, 1, 1, 0)]
++
++Criamos o subespaço sobre `\GF{2}` gerado pelas linhas acima.
++
++.. link
++
++::
++
++    sage: V = VectorSpace(GF(2),8)
++    sage: S = V.subspace(rows)
++    sage: S
++    Vector space of degree 8 and dimension 4 over Finite Field of size 2
++    Basis matrix:
++    [1 0 0 0 0 1 0 0]
++    [0 1 0 0 1 0 1 1]
++    [0 0 1 0 1 1 0 1]
++    [0 0 0 1 0 0 1 1]
++    sage: A.echelon_form()
++    [1 0 0 0 0 1 0 0]
++    [0 1 0 0 1 0 1 1]
++    [0 0 1 0 1 1 0 1]
++    [0 0 0 1 0 0 1 1]
++
++A base de `S` usada pelo Sage é obtida a partir das linhas não-nulas
++da forma escalonada da matriz de geradores de `S`.
++
++Álgebra Linear Esparsa
++----------------------
++
++O Sage fornece suporte para álgebra linear esparsa.
++
++::
++
++    sage: M = MatrixSpace(QQ, 100, sparse=True)
++    sage: A = M.random_element(density = 0.05)
++    sage: E = A.echelon_form()                  
++
++O algoritmo multi-modular no Sage é bom para matrizes quadradas (mas
++não muito bom para matrizes que não são quadradas):
++
++::
++
++    sage: M = MatrixSpace(QQ, 50, 100, sparse=True)
++    sage: A = M.random_element(density = 0.05)
++    sage: E = A.echelon_form()                  
++    sage: M = MatrixSpace(GF(2), 20, 40, sparse=True)
++    sage: A = M.random_element()
++    sage: E = A.echelon_form()
++
++Note que o Python é sensível a maiúsculas e minúsculas:
++
++::
++
++    sage: M = MatrixSpace(QQ, 10,10, Sparse=True)
++    Traceback (most recent call last):
++    ...
++    TypeError: MatrixSpace() got an unexpected keyword argument 'Sparse'
+diff --git a/doc/pt/tutorial/tour_numtheory.rst b/doc/pt/tutorial/tour_numtheory.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_numtheory.rst
+@@ -0,0 +1,168 @@
++Teoria de Números
++=================
++
++O Sage possui extensa funcionalidade para teoria de números. Por
++exemplo, podemos fazer aritmética em :math:`\ZZ/N\ZZ` da seguinte
++forma:
++
++::
++
++    sage: R = IntegerModRing(97)
++    sage: a = R(2) / R(3)
++    sage: a
++    33
++    sage: a.rational_reconstruction()
++    2/3
++    sage: b = R(47)
++    sage: b^20052005
++    50
++    sage: b.modulus()
++    97
++    sage: b.is_square()
++    True
++
++O Sage contém funções comuns em teoria de números. Por exemplo,
++
++::
++
++    sage: gcd(515,2005)
++    5
++    sage: factor(2005)
++    5 * 401
++    sage: c = factorial(25); c
++    15511210043330985984000000
++    sage: [valuation(c,p) for p in prime_range(2,23)]
++    [22, 10, 6, 3, 2, 1, 1, 1]
++    sage: next_prime(2005)
++    2011
++    sage: previous_prime(2005)
++    2003
++    sage: divisors(28); sum(divisors(28)); 2*28
++    [1, 2, 4, 7, 14, 28]
++    56
++    56
++
++Perfeito!
++
++A função ``sigma(n,k)`` do Sage soma as :math:`k`-ésimas potências dos
++divisores de ``n``:
++
++::
++
++    sage: sigma(28,0); sigma(28,1); sigma(28,2)
++    6
++    56
++    1050
++
++A seguir ilustramos o algoritmo de Euclides estendido, a função
++:math:`\phi` de Euler, e o teorema do resto Chinês:
++
++::
++
++    sage: d,u,v = xgcd(12,15)
++    sage: d == u*12 + v*15
++    True
++    sage: n = 2005
++    sage: inverse_mod(3,n)
++    1337
++    sage: 3 * 1337
++    4011
++    sage: prime_divisors(n)
++    [5, 401]
++    sage: phi = n*prod([1 - 1/p for p in prime_divisors(n)]); phi
++    1600
++    sage: euler_phi(n)
++    1600
++    sage: prime_to_m_part(n, 5)
++    401
++
++Agora verificamos algo sobre o problema :math:`3n+1`.
++
++::
++
++    sage: n = 2005
++    sage: for i in range(1000):
++    ...       n = 3*odd_part(n) + 1
++    ...       if odd_part(n)==1:
++    ...           print i
++    ...           break
++    38
++
++Por fim, ilustramos o teorema do resto Chinês.
++
++::
++
++    sage: x = crt(2, 1, 3, 5); x   
++    11
++    sage: x % 3  # x mod 3 = 2
++    2
++    sage: x % 5  # x mod 5 = 1
++    1
++    sage: [binomial(13,m) for m in range(14)]
++    [1, 13, 78, 286, 715, 1287, 1716, 1716, 1287, 715, 286, 78, 13, 1]
++    sage: [binomial(13,m)%2 for m in range(14)]
++    [1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1]
++    sage: [kronecker(m,13) for m in range(1,13)]
++    [1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1]
++    sage: n = 10000; sum([moebius(m) for m in range(1,n)])
++    -23
++    sage: list(partitions(4))
++    [(1, 1, 1, 1), (1, 1, 2), (2, 2), (1, 3), (4,)]
++
++Números :math:`p`-ádicos
++------------------------
++
++O corpo dos números :math:`p`-ádicos está implementado em Sage. Note
++que uma vez que um corpo :math:`p`-ádico é criado, você não pode
++alterar a sua precisão.
++
++::
++
++    sage: K = Qp(11); K
++    11-adic Field with capped relative precision 20
++    sage: a = K(211/17); a
++    4 + 4*11 + 11^2 + 7*11^3 + 9*11^5 + 5*11^6 + 4*11^7 + 8*11^8 + 7*11^9 
++      + 9*11^10 + 3*11^11 + 10*11^12 + 11^13 + 5*11^14 + 6*11^15 + 2*11^16 
++      + 3*11^17 + 11^18 + 7*11^19 + O(11^20)
++    sage: b = K(3211/11^2); b
++    10*11^-2 + 5*11^-1 + 4 + 2*11 + O(11^18)
++
++Muito trabalho foi feito implementando anéis de inteiros em corpos
++:math:`p`-ádicos ou corpos numéricos além de `Z`. O leitor
++interessado é convidado a perguntar mais detalhes aos especialistas na
++lista ``sage-support`` no Google Groups.
++
++Diversos métodos relacionados já estão implementados na classe
++NumberField.
++
++::
++
++    sage: R.<x> = PolynomialRing(QQ)
++    sage: K = NumberField(x^3 + x^2 - 2*x + 8, 'a')
++    sage: K.integral_basis()
++    [1, 1/2*a^2 + 1/2*a, a^2]
++
++.. link
++
++::
++
++    sage: K.galois_group(type="pari")
++    Galois group PARI group [6, -1, 2, "S3"] of degree 3 of the Number Field 
++    in a with defining polynomial x^3 + x^2 - 2*x + 8
++
++.. link
++
++::
++
++    sage: K.polynomial_quotient_ring()
++    Univariate Quotient Polynomial Ring in a over Rational Field with modulus 
++    x^3 + x^2 - 2*x + 8
++    sage: K.units()
++    [3*a^2 + 13*a + 13]
++    sage: K.discriminant()
++    -503
++    sage: K.class_group()
++    Class group of order 1 of Number Field in a with 
++    defining polynomial x^3 + x^2 - 2*x + 8
++    sage: K.class_number()
++    1
+diff --git a/doc/pt/tutorial/tour_plotting.rst b/doc/pt/tutorial/tour_plotting.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_plotting.rst
+@@ -0,0 +1,231 @@
++.. _section-plot:
++
++Gráficos
++========
++
++O Sage pode produzir gráficos bidimensionais e tridimensionais.
++
++Gráficos Bidimensionais
++-----------------------
++
++Em duas dimensões, o Sage pode desenhar círculos, linhas, e polígonos;
++gráficos de funções em coordenadas retangulares, e também coordenadas
++polares; gráficos de contorno e gráficos de campos vetoriais.
++Apresentamos alguns exemplos desses gráficos aqui. Para mais exemplos
++de gráficos com o Sage, veja :ref:`section-systems` e
++:ref:`section-maxima`, e também a documentação `Sage Constructions
++<http://www.sagemath.org/doc/constructions/>`_.
++
++Este comando produz um círculo amarelo de raio 1, centrado na origem.
++
++::
++
++    sage: circle((0,0), 1, rgbcolor=(1,1,0))
++
++Você pode também produzir um círculo preenchido:
++
++::
++
++    sage: circle((0,0), 1, rgbcolor=(1,1,0), fill=True)
++
++Outra possibilidade é criar um círculo atribuindo-o a uma variável;
++isso não cria um gráfico:
++
++::
++
++    sage: c = circle((0,0), 1, rgbcolor=(1,1,0))
++
++Para criar o gráfico, use ``c.show()`` ou ``show(c)``, da seguinte
++forma:
++
++.. link
++
++::
++
++    sage: c.show()
++
++Alternativamente, o comando ``c.save('filename.png')`` salva o gráfico
++no arquivo citado.
++
++Agora, esses 'círculos' parecem mais elipses porque os eixos estão em
++escalas diferentes. Você pode alterar isso:
++
++.. link
++
++::
++
++    sage: c.show(aspect_ratio=1)
++
++O comando ``show(c, aspect_ratio=1)`` produz o mesmo resultado, ou
++você pode salvar a figura usando ``c.save('filename.png',
++aspect_ratio=1)``.
++
++É fácil criar o gráfico de funções simples:
++
++::
++
++    sage: plot(cos, (-5,5))
++
++Após especificar uma variável, você também pode criar gráficos
++paramétricos:
++
++::
++
++    sage: x = var('x')
++    sage: parametric_plot((cos(x),sin(x)^3),(x,0,2*pi),rgbcolor=hue(0.6))
++
++É importante notar que os eixos dos gráficos vão se intersectar apenas
++se a origem estiver no escopo do gráfico, e que valores grandes podem
++ser representados usando notação científica.
++
++::
++
++    sage: plot(x^2,(x,300,500))
++
++Você pode combinar vários gráficos somando-os:
++
++::
++
++    sage: x = var('x')
++    sage: p1 = parametric_plot((cos(x),sin(x)),(x,0,2*pi),rgbcolor=hue(0.2))
++    sage: p2 = parametric_plot((cos(x),sin(x)^2),(x,0,2*pi),rgbcolor=hue(0.4))
++    sage: p3 = parametric_plot((cos(x),sin(x)^3),(x,0,2*pi),rgbcolor=hue(0.6))
++    sage: show(p1+p2+p3, axes=false)
++
++Uma boa forma de produzir figuras preenchidas é criar uma lista de
++pontos (``L`` no exemplo abaixo) e então usar o comando ``polygon``
++para fazer o gráfico do polígono formado por esses pontos. Por
++exemplo, aqui está um "deltoid" verde:
++
++::
++
++    sage: L = [[-1+cos(pi*i/100)*(1+cos(pi*i/100)),\
++    ...   2*sin(pi*i/100)*(1-cos(pi*i/100))] for i in range(200)]
++    sage: p = polygon(L, rgbcolor=(1/8,3/4,1/2))
++    sage: p
++
++Digite ``show(p, axes=false)`` para visualizar isso sem os eixos.
++
++Você pode adicionar texto ao gráfico:
++
++::
++
++    sage: L = [[6*cos(pi*i/100)+5*cos((6/2)*pi*i/100),\
++    ...   6*sin(pi*i/100)-5*sin((6/2)*pi*i/100)] for i in range(200)]
++    sage: p = polygon(L, rgbcolor=(1/8,1/4,1/2))
++    sage: t = text("hypotrochoid", (5,4), rgbcolor=(1,0,0))
++    sage: show(p+t)
++
++Professores de cálculo frequentemente desenham o seguinte gráfico na
++lousa: não apenas um ramo do arco-seno, mas vários deles: isto é, o
++gráfico de :math:`y=\sin(x)` para :math:`x` entre :math:`-2\pi` e
++:math:`2\pi`, refletido com respeito a reta :math:`x=y`. Os seguintes
++comandos fazem isso:
++
++::
++
++    sage: v = [(sin(x),x) for x in srange(-2*float(pi),2*float(pi),0.1)]
++    sage: line(v)
++
++Como a função tangente possui imagem maior do que o seno, se você usar
++o mesmo método para fazer o gráfico da função inversa da função
++tangente, você deve alterar as coordenadas mínima e máxima para o eixo
++*x*:
++
++::
++
++    sage: v = [(tan(x),x) for x in srange(-2*float(pi),2*float(pi),0.01)]
++    sage: show(line(v), xmin=-20, xmax=20)
++
++O Sage também cria gráficos usando coordenadas polares, gráficos de
++contorno e gráficos de campos vetoriais (para tipos especiais de
++funções). Aqui está um exemplo de gráfico de contorno:
++
++::
++
++    sage: f = lambda x,y: cos(x*y)
++    sage: contour_plot(f, (-4, 4), (-4, 4))
++
++Gráficos Tridimensionais
++------------------------
++
++O Sage pode ser usado para criar gráficos tridimensionais. Tanto no
++Sage Notebook, como no console (linha de comando), esses gráficos serão
++exibidos usando o software de código aberto [Jmol]_, que permite girar
++e ampliar a figura usando o mouse.
++
++Use ``plot3d`` para criar o gráfico de uma função da forma `f(x, y) =
++z`:
++
++::
++
++    sage: x, y = var('x,y')
++    sage: plot3d(x^2 + y^2, (x,-2,2), (y,-2,2))
++
++Alternativamente, você pode usar ``parametric_plot3d`` para criar o
++gráfico de uma superfície onde cada coordenada `x, y, z` é determinada
++por uma função de uma ou duas variáveis (os parâmetros, tipicamente
++`u` e `v`). O gráfico anterior pode ser representado parametricamente
++na forma:
++
++::
++
++    sage: u, v = var('u, v')
++    sage: f_x(u, v) = u
++    sage: f_y(u, v) = v
++    sage: f_z(u, v) = u^2 + v^2
++    sage: parametric_plot3d([f_x, f_y, f_z], (u, -2, 2), (v, -2, 2))
++
++A terceira forma de fazer um gráfico de uma superfície no Sage é
++usando o comando ``implicit_plot3d``, que cria um gráfico de uma
++superfície definida por uma equação `f(x, y, z) = 0` (isso define um
++conjunto de pontos). Vamos fazer o gráfico de uma esfera usando a
++expressão usual:
++
++::
++
++    sage: x, y, z = var('x, y, z')
++    sage: implicit_plot3d(x^2 + y^2 + z^2 - 4, (x,-2, 2), (y,-2, 2), (z,-2, 2))
++
++Aqui estão mais alguns exemplos:
++
++`Yellow Whitney's umbrella <http://en.wikipedia.org/wiki/Whitney_umbrella>`__:
++
++::
++
++    sage: u, v = var('u,v')
++    sage: fx = u*v
++    sage: fy = u
++    sage: fz = v^2
++    sage: parametric_plot3d([fx, fy, fz], (u, -1, 1), (v, -1, 1),
++    ...   frame=False, color="yellow")
++
++`Cross cap <http://en.wikipedia.org/wiki/Cross-cap>`__:
++
++::
++
++    sage: u, v = var('u,v')
++    sage: fx = (1+cos(v))*cos(u)
++    sage: fy = (1+cos(v))*sin(u)
++    sage: fz = -tanh((2/3)*(u-pi))*sin(v)
++    sage: parametric_plot3d([fx, fy, fz], (u, 0, 2*pi), (v, 0, 2*pi),
++    ...   frame=False, color="red")
++
++Toro retorcido:
++
++::
++
++    sage: u, v = var('u,v')
++    sage: fx = (3+sin(v)+cos(u))*cos(2*v)
++    sage: fy = (3+sin(v)+cos(u))*sin(2*v)
++    sage: fz = sin(u)+2*cos(v)
++    sage: parametric_plot3d([fx, fy, fz], (u, 0, 2*pi), (v, 0, 2*pi),
++    ...   frame=False, color="red")
++
++Lemniscata:
++
++::
++
++    sage: x, y, z = var('x,y,z')
++    sage: f(x, y, z) = 4*x^2 * (x^2 + y^2 + z^2 + z) + y^2 * (y^2 + z^2 - 1)
++    sage: implicit_plot3d(f, (x, -0.5, 0.5), (y, -1, 1), (z, -1, 1))
+diff --git a/doc/pt/tutorial/tour_polynomial.rst b/doc/pt/tutorial/tour_polynomial.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_polynomial.rst
+@@ -0,0 +1,332 @@
++.. _section-poly:
++
++Polinômios
++==========
++
++Nesta seção vamos ilustrar como criar e usar polinômios no Sage.
++
++
++.. _section-univariate:
++
++Polinômios em Uma Variável
++--------------------------
++
++Existem três formas de criar anéis de polinômios.
++
++::
++
++    sage: R = PolynomialRing(QQ, 't')
++    sage: R
++    Univariate Polynomial Ring in t over Rational Field
++
++Esse comando cria um anel de polinômios e diz para o Sage usar a letra
++'t' para representar a variável indeterminada quando imprimir na tela.
++Todavia, isso não define o símbolo ``t`` para uso no Sage, logo você
++não pode usá-lo para definir um polinômio (como :math:`t^2+1`)
++pertencente a ``R``.
++
++Uma forma alternativa é
++
++.. link
++
++::
++
++    sage: S = QQ['t']
++    sage: S == R
++    True
++
++As mesmas observações com respeito a ``t`` valem também nesse caso.
++
++Uma terceira e conveniente forma de definir polinômios é
++
++::
++
++    sage: R.<t> = PolynomialRing(QQ)
++
++ou
++
++::
++
++    sage: R.<t> = QQ['t']
++
++ou ainda
++
++::
++
++    sage: R.<t> = QQ[]
++
++Isso tem o efeito colateral de definir a variável ``t`` como a
++variável indeterminada do anel de polinômios, logo você pode
++facilmente construir elementos de ``R`` da seguinte forma. (Note que
++essa terceira alternativa é muito semelhante à notação usada em Magma,
++e da mesma forma que no Magma ela pode ser usada para diversos tipos
++de objetos.)
++
++.. link
++
++::
++
++    sage: poly = (t+1) * (t+2); poly
++    t^2 + 3*t + 2
++    sage: poly in R
++    True
++
++Qualquer que seja o método usado para definir um anel de polinômios,
++você pode recuperar a variável indeterminada como o :math:`0`-ésimo
++gerador:
++
++::
++
++    sage: R = PolynomialRing(QQ, 't')
++    sage: t = R.0
++    sage: t in R
++    True
++
++Note que uma construção similar funciona com os números complexos: os
++números complexos podem ser vistos como sendo gerados pelo símbolo
++``i`` sobre os números reais; logo temos o seguinte:
++
++::
++
++    sage: CC
++    Complex Field with 53 bits of precision
++    sage: CC.0  # 0th generator of CC
++    1.00000000000000*I
++
++Para anel de polinômios, você pode obter tanto o anel como o seu
++gerador, ou somente o gerador, no momento em que o anel for criado, da
++seguinte forma:
++
++::
++
++    sage: R, t = QQ['t'].objgen()
++    sage: t    = QQ['t'].gen()
++    sage: R, t = objgen(QQ['t'])
++    sage: t    = gen(QQ['t'])
++
++Finalmente apresentamos um pouco de aritmética em :math:`\QQ[t]`.
++
++::
++
++    sage: R, t = QQ['t'].objgen()
++    sage: f = 2*t^7 + 3*t^2 - 15/19
++    sage: f^2
++    4*t^14 + 12*t^9 - 60/19*t^7 + 9*t^4 - 90/19*t^2 + 225/361
++    sage: cyclo = R.cyclotomic_polynomial(7); cyclo
++    t^6 + t^5 + t^4 + t^3 + t^2 + t + 1
++    sage: g = 7 * cyclo * t^5 * (t^5 + 10*t + 2)
++    sage: g
++    7*t^16 + 7*t^15 + 7*t^14 + 7*t^13 + 77*t^12 + 91*t^11 + 91*t^10 + 84*t^9 
++           + 84*t^8 + 84*t^7 + 84*t^6 + 14*t^5
++    sage: F = factor(g); F
++    (7) * t^5 * (t^5 + 10*t + 2) * (t^6 + t^5 + t^4 + t^3 + t^2 + t + 1)
++    sage: F.unit()
++    7
++    sage: list(F)
++    [(t, 5), (t^5 + 10*t + 2, 1), (t^6 + t^5 + t^4 + t^3 + t^2 + t + 1, 1)]
++
++Note que a fatorização corretamente leva em conta e armazena a parte
++unitária.
++
++Se você fosse usar, por exemplo, a função ``R.cyclotomic_polynomial``
++intensamente para algum projeto de pesquisa, além de citar o Sage,
++você deveria tentar descobrir qual componente do Sage é de fato usado
++para calcular esses polinômios, e citá-lo também. Nesse caso, se você
++digitar ``R.cyclotomic_polynomial??`` para ver o código fonte, você
++irá facilmente ver uma linha ``f = pari.polcyclo(n)`` o que significa
++que o PARI é usado para o cálculo dos polinômios ciclotrômicos. Cite o
++PARI também no seu trabalho.
++
++Dividindo dois polinômios cria-se um elemento do corpo de frações (o
++qual o Sage cria automaticamente).
++
++::
++
++    sage: x = QQ['x'].0
++    sage: f = x^3 + 1; g = x^2 - 17
++    sage: h = f/g;  h
++    (x^3 + 1)/(x^2 - 17)
++    sage: h.parent()
++    Fraction Field of Univariate Polynomial Ring in x over Rational Field
++
++Usando-se a série de Laurent, pode-se calcular a expansão em série no
++corpo de frações de ``QQ[x]``:
++
++::
++
++    sage: R.<x> = LaurentSeriesRing(QQ); R
++    Laurent Series Ring in x over Rational Field
++    sage: 1/(1-x) + O(x^10)
++    1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + O(x^10)
++
++Se nomearmos a variável de outra forma, obtemos um anel de polinômios
++em uma variável diferente.
++
++::
++
++    sage: R.<x> = PolynomialRing(QQ)
++    sage: S.<y> = PolynomialRing(QQ)
++    sage: x == y
++    False
++    sage: R == S
++    False
++    sage: R(y)
++    x
++    sage: R(y^2 - 17)
++    x^2 - 17
++
++O anel é determinado pela variável. Note que criar um outro anel com
++variável indeterminada ``x`` não retorna um anel diferente.
++
++::
++
++    sage: R = PolynomialRing(QQ, "x")
++    sage: T = PolynomialRing(QQ, "x")
++    sage: R == T
++    True      
++    sage: R is T
++    True
++    sage: R.0 == T.0
++    True
++
++O Sage também possui suporte para séries de potências e séries de
++Laurent sobre um anel arbitrário. No seguinte exemplo, nós criamos um
++elemento de :math:`\GF{7}[[T]]` e dividimos para criar um elemento de
++:math:`\GF{7}((T))`.
++
++::
++
++    sage: R.<T> = PowerSeriesRing(GF(7)); R
++    Power Series Ring in T over Finite Field of size 7
++    sage: f = T  + 3*T^2 + T^3 + O(T^4)
++    sage: f^3
++    T^3 + 2*T^4 + 2*T^5 + O(T^6)
++    sage: 1/f
++    T^-1 + 4 + T + O(T^2)
++    sage: parent(1/f)
++    Laurent Series Ring in T over Finite Field of size 7
++
++Você também pode criar anéis de polinômios usando a notação de
++colchetes duplos:
++
++::
++
++    sage: GF(7)[['T']]
++    Power Series Ring in T over Finite Field of size 7
++
++Polinômios em Mais De Uma Variável
++----------------------------------
++
++Para trabalhar com polinômios em várias variáveis, nós primeiro
++declaramos o anel de polinômios e as variáveis.
++
++::
++
++    sage: R = PolynomialRing(GF(5),3,"z") # here, 3 = number of variables
++    sage: R
++    Multivariate Polynomial Ring in z0, z1, z2 over Finite Field of size 5
++
++Da mesma forma como ocorre com polinômios em uma variável, existem
++três maneiras de fazer isso:
++
++::
++
++    sage: GF(5)['z0, z1, z2']
++    Multivariate Polynomial Ring in z0, z1, z2 over Finite Field of size 5
++    sage: R.<z0,z1,z2> = GF(5)[]; R
++    Multivariate Polynomial Ring in z0, z1, z2 over Finite Field of size 5
++
++Se você quiser usar os nomes das variáveis com apenas uma letra, então
++você pode usar os seguinte comando:
++
++::
++
++    sage: PolynomialRing(GF(5), 3, 'xyz')
++    Multivariate Polynomial Ring in x, y, z over Finite Field of size 5
++
++A seguir fazemos um pouco de aritmética.
++
++::
++
++    sage: z = GF(5)['z0, z1, z2'].gens()
++    sage: z
++    (z0, z1, z2)
++    sage: (z[0]+z[1]+z[2])^2
++    z0^2 + 2*z0*z1 + z1^2 + 2*z0*z2 + 2*z1*z2 + z2^2
++
++Você também pode usar uma notação mais matemática para criar um anel
++de polinômios.
++
++::
++
++    sage: R = GF(5)['x,y,z']
++    sage: x,y,z = R.gens()
++    sage: QQ['x']
++    Univariate Polynomial Ring in x over Rational Field
++    sage: QQ['x,y'].gens()
++    (x, y)
++    sage: QQ['x'].objgens()
++    (Univariate Polynomial Ring in x over Rational Field, (x,))
++
++Polinômios em mais de uma variável são implementados no Sage usando
++dicionários em Python e a "representação distribuída" de um polinômio.
++O Sage usa o Singular [Si]_, por exemplo, para o cálculo do maior
++divisor comum e bases de Gröbner para ideais algébricos.
++
++::
++
++    sage: R, (x, y) = PolynomialRing(RationalField(), 2, 'xy').objgens()
++    sage: f = (x^3 + 2*y^2*x)^2
++    sage: g = x^2*y^2
++    sage: f.gcd(g)
++    x^2
++
++A seguir criamos o ideal :math:`(f,g)` gerado por :math:`f` e
++:math:`g`, simplesmente multiplicando ``(f,g)`` por ``R`` (nós
++poderíamos também escrever ``ideal([f,g])`` ou ``ideal(f,g)``).
++
++.. link
++
++::
++
++    sage: I = (f, g)*R; I
++    Ideal (x^6 + 4*x^4*y^2 + 4*x^2*y^4, x^2*y^2) of Multivariate Polynomial 
++    Ring in x, y over Rational Field
++    sage: B = I.groebner_basis(); B
++    [x^6, x^2*y^2]
++    sage: x^2 in I
++    False
++
++A base de Gröbner acima não é uma lista mas sim uma sequência
++imutável. Isso implica que ela possui universo (universe) e parente
++(parent), e não pode ser modificada (o que é bom pois ocasionaria
++erros em outras rotinas que usam bases de Gröbner).
++
++.. link
++
++::
++
++    sage: B.parent()
++    Category of sequences in Multivariate Polynomial Ring in x, y over Rational 
++    Field
++    sage: B.universe()
++    Multivariate Polynomial Ring in x, y over Rational Field
++    sage: B[1] = x
++    Traceback (most recent call last):
++    ...
++    ValueError: object is immutable; please change a copy instead.
++
++Um pouco (não tanto quanto gostaríamos) de álgebra comutativa está
++disponível no Sage, implementado via Singular. Por exemplo, podemos
++calcular a decomposição primaria e primos associados de :math:`I`:
++
++.. link
++
++::
++
++    sage: I.primary_decomposition()
++    [Ideal (x^2) of Multivariate Polynomial Ring in x, y over Rational Field,
++     Ideal (y^2, x^6) of Multivariate Polynomial Ring in x, y over Rational Field]
++    sage: I.associated_primes()
++    [Ideal (x) of Multivariate Polynomial Ring in x, y over Rational Field,
++     Ideal (y, x) of Multivariate Polynomial Ring in x, y over Rational Field]
+diff --git a/doc/pt/tutorial/tour_rings.rst b/doc/pt/tutorial/tour_rings.rst
+new file mode 100644
+--- /dev/null
++++ b/doc/pt/tutorial/tour_rings.rst
+@@ -0,0 +1,148 @@
++.. _section-rings:
++
++Anéis Básicos
++=============
++
++Quando se define matrizes, vetores, ou polinômios, é as vezes útil, e
++as vezes necessário, especificar o "anel" sobre o qual o objeto será
++definido. Um *anel* é uma estrutura matemática na qual se tem noções
++de adição e multiplicação bem definidas; se você nunca ouviu falar
++sobre anéis, você provavelmente só precisa saber a respeito dos
++seguintes exemplos:
++
++* os inteiros `\{..., -1, 0, 1, 2,... \}`, que são chamados ``ZZ`` no
++  Sage.
++* os números racionais -- i. e., frações, ou razões, de inteiros --
++  que são chamados ``QQ`` no Sage.
++* os números reais, chamados de ``RR`` no Sage.
++* os números complexos, chamados de ``CC`` no Sage.
++
++Você pode precisar saber sobre essas distinções porque o mesmo
++polinômio, por exemplo, pode ser tratado diferentemente dependendo do
++anel sobre o qual está definido. A propósito, o polinômio `x^2-2`
++possui duas raízes, `\pm \sqrt{2}`. Essas raízes não são racionais,
++logo, se você esta lidando com polinômios com coeficientes racionais,
++os polinômios não serão fatorados. Com coeficientes reais, eles serão.
++Portanto você pode querer especificar o anel para garantir que você
++vai obter a informação que deseja. Os dois comandos a seguir definem
++os conjuntos de polinômios com coeficientes racionais e coeficientes
++reais, respectivamente. Os conjuntos são chamados "ratpoly" e
++"realpoly", mas esses nomes não são importantes aqui; todavia, note
++que as strings ".<t>" e ".<z>" especificam o nome das variáveis
++usadas em cada caso.
++
++::
++
++    sage: ratpoly.<t> = PolynomialRing(QQ)
++    sage: realpoly.<z> = PolynomialRing(RR)
++
++Agora ilustramos a nossa discussão sobre fatorar `x^2-2`:
++
++.. link
++
++::
++
++    sage: factor(t^2-2)
++    t^2 - 2
++    sage: factor(z^2-2)
++    (z - 1.41421356237310) * (z + 1.41421356237310)
++
++Comentários similares também se aplicam a matrizes: a forma reduzida
++de uma matriz pode depender do anel sobre o qual ela esta definida,
++como também pode os seus autovalores e autovetores. Para mais sobre
++polinômios, veja :ref:`section-poly`, para mais sobre matrizes, veja
++:ref:`section-linalg`.
++
++O símbolo ``I`` representa a raiz quadrada de :math:`-1`; ``i`` é um
++sinônimo de ``I``. Obviamente, isso não é um número racional::
++
++    sage: i  # square root of -1
++    I     
++    sage: i in QQ
++    False
++
++Nota: O código acima pode não funcionar como esperado se a variável
++``i`` estiver atribuída a um outro valor, por exemplo, se ela for
++usada como a variável de um laço (loop). Nesse caso, digite::
++
++    sage: reset('i')
++
++para restabelecer o valor original de ``i``.
++
++Há uma sutileza ao definir números complexos: como mencionado acima,
++o símbolo ``i`` representa a raiz quadrada de `-1`, mas é uma raiz
++quadrada de `-1` *formal* ou *simbólica*. Evocando ``CC(i)`` ou
++``CC.0`` obtém-se a raiz de `-1` complexa. Aritmética envolvendo tipos
++diferentes de números é possível graças ao que se chama de coação,
++veja :ref:`section-coercion`.
++
++::
++
++    sage: i = CC(i)       # floating point complex number
++    sage: i == CC.0
++    True
++    sage: a, b = 4/3, 2/3
++    sage: z = a + b*i
++    sage: z
++    1.33333333333333 + 0.666666666666667*I
++    sage: z.imag()        # imaginary part
++    0.666666666666667
++    sage: z.real() == a   # automatic coercion before comparison
++    True
++    sage: a + b
++    2
++    sage: 2*b == a
++    True
++    sage: parent(2/3)
++    Rational Field
++    sage: parent(4/2)
++    Rational Field
++    sage: 2/3 + 0.1       # automatic coercion before addition
++    0.766666666666667
++    sage: 0.1 + 2/3       # coercion rules are symmetric in SAGE
++    0.766666666666667
++
++Aqui estão mais exemplos de anéis básicos em Sage. Como observado
++acima, o anel dos números racionais pode ser referido usando ``QQ``,
++ou também ``RationalField()`` (um *corpo*, ou *field* em inglês, é um
++anel no qual a operação de multiplicação é comutativa, e todo elemento
++não-nulo possui um elemento inverso com respeito à operação de
++multiplicação. Logo, os racionais formam um corpo, mas os inteiros
++não)::
++
++    sage: RationalField()
++    Rational Field
++    sage: QQ
++    Rational Field
++    sage: 1/2 in QQ
++    True
++
++O número decimal ``1.2`` é considerado como um elemento de ``QQ``:
++número decimais que são também racionais podem ser coagidos ao conjunto de
++números racionais (veja :ref:`section-coercion`). Os números `\pi` e
++`\sqrt{2}` não são racionais, todavia::
++
++    sage: 1.2 in QQ
++    True
++    sage: pi in QQ
++    False
++    sage: pi in RR
++    True
++    sage: sqrt(2) in QQ
++    False
++    sage: sqrt(2) in CC
++    True
++
++Para uso em matemática mais avançada, o Sage também pode especificar
++outros anéis, como corpos finitos, inteiros `p`-ádicos, o anel dos
++números algébricos, anéis de polinômios, e anéis de matrizes. Aqui
++está a construção de alguns deles::
++
++    sage: GF(3)
++    Finite Field of size 3
++    sage: GF(27, 'a')  # need to name the generator if not a prime field
++    Finite Field in a of size 3^3
++    sage: Zp(5)
++    5-adic Ring with capped relative precision 20
++    sage: sqrt(3) in QQbar # algebraic closure of QQ
++    True
diff --git a/trac_12822_pt_translation_of_tutorial_rev1.patch b/trac_12822_pt_translation_of_tutorial_rev1.patch
new file mode 100644
index 0000000..145cc9d
--- /dev/null
+++ b/trac_12822_pt_translation_of_tutorial_rev1.patch
@@ -0,0 +1,468 @@
+# HG changeset patch
+# User Gustavo de Oliveira <goliveira5d at gmail.com>
+# Date 1336320704 -7200
+# Node ID f35ca5dd36d8ccfeba96947e9e10402f6e6ed79b
+# Parent  ad8e41651a3187a45f087335cb048418bf545506
+Trac 12822: Portuguese translation of "Tutorial" (revision 1).
+
+diff --git a/doc/pt/tutorial/interactive_shell.rst b/doc/pt/tutorial/interactive_shell.rst
+--- a/doc/pt/tutorial/interactive_shell.rst
++++ b/doc/pt/tutorial/interactive_shell.rst
+@@ -361,8 +361,8 @@
+ 
+ Note que o GAP e o Maxima são os mais lentos neste teste (isso foi
+ executado no computador ``sage.math.washington.edu``). Devido ao
+-"overhead" da interface pexpect, talvez não seja apropriado comparar
+-esses resultados com o Sage, que é o mais rápido.
++processamento extra (overhead) da interface pexpect, talvez não seja
++apropriado comparar esses resultados com o Sage, que é o mais rápido.
+ 
+ Outras Dicas para o IPython
+ ===========================
+@@ -402,7 +402,7 @@
+ 
+ - Você pode usar ``%edit`` (ou ``%ed`` ou ``ed``) para abrir um
+   editor, se você desejar digitar algum código mais complexo. Antes de
+-  iniciar o Sage, certifique-se de que a variável de environment
++  iniciar o Sage, certifique-se de que a variável de ambiente
+   :envvar:`EDITOR` está definida com o seu editor favorito (colocando
+   ``export EDITOR=/usr/bin/emacs`` ou ``export EDITOR=/usr/bin/vim``
+   or algo similar no lugar apropriado, como um arquivo ``.profile``).
+@@ -789,7 +789,7 @@
+     sage: v = E.anlist(100000)              # instant!
+ 
+ (Em Python, salvar e restaurar é feito usando o módulo ``cPickle``. Em
+-particular, um objeto ``x`` do Sage pode ser salvado usando
++particular, um objeto ``x`` do Sage pode ser salvo usando
+ ``cPickle.dumps(x, 2)``. Note o ``2``!)
+ 
+ O sage não pode salvar e carregar objetos criados em algum outro
+@@ -811,7 +811,7 @@
+     ValueError: The session in which this object was defined is no longer 
+     running.
+ 
+-Objetos do GP/PARI também podem ser salvados e carregados pois suas
++Objetos do GP/PARI também podem ser salvos e carregados pois suas
+ representações em forma impressa são suficientes para reconstruí-los.
+ 
+ .. skip
+@@ -823,7 +823,7 @@
+     sage: load('a')
+     2
+ 
+-Objetos que foram salvados podem ser abertos posteriormente em
++Objetos que foram salvos podem ser abertos posteriormente em
+ computadores com arquiteturas e sistemas operacionais diferentes, por
+ exemplo, você poderia salvar uma matriz muito grande em um OS X de
+ 32-bits e abri-lo em um Linux de 64-bits, encontrar a forma reduzida,
+@@ -868,7 +868,7 @@
+ ``sessionname``. (No caso raro de uma variável não poder ser salva,
+ ela simplesmente não aparece no dicionário.) O resultado é um arquivo
+ ``.sobj`` que pode ser aberto como qualquer outro objeto que foi
+-salvado. Quando você abre os objetos que foram salvados em uma sessão,
++salvo. Quando você abre os objetos que foram salvos em uma sessão,
+ você obtém um dicionário cujas chaves (keys) são os nomes das
+ variáveis e os valores são os objetos.
+ 
+@@ -954,7 +954,7 @@
+     sage: notebook()
+ 
+ na linha de comando do Sage. Isso inicia o Notebook e abre o seu
+-browser padrão para visualizá-lo. Os arquivos de estado do servidor
++navegador padrão para visualizá-lo. Os arquivos de estado do servidor
+ são armazenados em ``$HOME/.sage/sage\_notebook``.
+ 
+ Outras opções incluem:
+diff --git a/doc/pt/tutorial/interfaces.rst b/doc/pt/tutorial/interfaces.rst
+--- a/doc/pt/tutorial/interfaces.rst
++++ b/doc/pt/tutorial/interfaces.rst
+@@ -48,15 +48,15 @@
+     Mod(5, 10007)
+ 
+ No primeiro caso, uma cópia separada do interpretador GP é iniciada
+-como um servidor, e a string ``´znprimroot(10007)'`` é enviada,
++como um servidor, e a string ``znprimroot(10007)`` é enviada,
+ calculada pelo GP, e o resultado é armazenado em uma variável no GP
+ (que ocupa espaço na memória dos processos do GP que não serão
+ liberados). Então o valor dessa variável é exibido. No segundo caso,
+-nenhum programa separado é iniciado, e a string
+-``´znprimroot(10007)'`` é calculada por uma certa função da biblioteca
+-C do PARI. O resultado é armazenado na memória em uso pelo Python, que
+-é liberada quando a variável não for mais referenciada. Os objetos
+-possuem tipos diferentes:
++nenhum programa separado é iniciado, e a string ``znprimroot(10007)``
++é calculada por uma certa função da biblioteca C do PARI. O resultado
++é armazenado na memória em uso pelo Python, que é liberada quando a
++variável não for mais referenciada. Os objetos possuem tipos
++diferentes:
+ 
+ ::
+ 
+@@ -187,7 +187,7 @@
+ ========
+ 
+ O Singular fornece uma biblioteca massiva e madura para bases de
+-Gröbner, máximo divisor comum para poliômios em várias variaveis,
++Gröbner, máximo divisor comum para polinômios em várias variáveis,
+ bases de espaços de Riemann-Roch de uma curva plana, e fatorização,
+ entre outras coisas. Vamos ilustrar a fatorização de polinômios em
+ várias variáveis usando a interface do Sage para o Singular (não
+diff --git a/doc/pt/tutorial/introduction.rst b/doc/pt/tutorial/introduction.rst
+--- a/doc/pt/tutorial/introduction.rst
++++ b/doc/pt/tutorial/introduction.rst
+@@ -68,7 +68,7 @@
+ principal do Sage [SA]_ para instruções de como instalar o Sage no seu
+ computador. Aqui faremos apenas alguns comentários.
+ 
+-#. O arquivo para download do Sage vem com "baterias incluídas". Em
++#. O arquivo para instalação do Sage vem com "baterias incluídas". Em
+    outras palavras, embora o Sage use o Python, IPython, PARI, GAP,
+    Singular, Maxima, NTL, GMP, e uma série de outros programas, você
+    não precisa instalá-los separadamente pois eles estão incluídos no
+diff --git a/doc/pt/tutorial/latex.rst b/doc/pt/tutorial/latex.rst
+--- a/doc/pt/tutorial/latex.rst
++++ b/doc/pt/tutorial/latex.rst
+@@ -31,15 +31,15 @@
+ 
+ #. A interface Notebook é configurada para usar o `jsMath
+    <http://www.math.union.edu/~dpvc/jsMath/>`_ para representar
+-   fórmulas matemáticas de forma clara em um web browser. O jsMath é
++   fórmulas matemáticas de forma clara em um web navegador. O jsMath é
+    uma coleção de rotinas em JavaScript e fontes associadas.
+    Tipicamente esses fontes ficam armazenadas em um servidor e são
+-   enviadas para o browser juntamente com a página onde elas estão
++   enviadas para o navegador juntamente com a página onde elas estão
+    sendo usadas. No caso do Sage, o Notebook está sempre conectado a
+    um servidor usado para executar os comando do Sage, e esse servidor
+    também fornece as fontes do jsMath necessárias. Logo não é
+    necessário configurar nada mais para ter formulas matemáticas
+-   representadas no seu browser quando você usa o Notebook do Sage.
++   representadas no seu navegador quando você usa o Notebook do Sage.
+ 
+    O jsMath é implementado para representar um subconjunto grande,
+    mas não completo, do TeX. Ele não suporta objetos como, por
+@@ -154,7 +154,7 @@
+ Um segundo recurso disponível no Notebook é possibilidade de inserir
+ código TeX para fazer anotações na folha de trabalho. Quando o cursos
+ esta posicionado entre células de modo que uma barra azul fica
+-visível, então shift-click irá abrir um mini processador de texto,
++visível, então shift+clique irá abrir um mini processador de texto,
+ TinyMCE. Isso permite digitar texto, usando um editor WSISYG para
+ criar HTML e CSS. Logo é possível inserir texto formatado para
+ complementar a folha de trabalho. Todavia, texto entre símbolos $, ou
+@@ -176,8 +176,9 @@
+ usado para alterar a notação de matrizes -- parênteses grandes,
+ colchetes, barras verticais. Nenhuma noção de estilo é enfatizada,
+ você pode configurar como desejado. Observe como as barras invertidas
+-usadas em LaTeX requerem uma barra adicional de modo que elas possam
+-ser interpretadas (escaped) corretamente em uma string do Python. ::
++usadas em LaTeX requerem uma barra adicional para que elas não sejam
++interpretadas pelo Python como um comando (ou seja, sejam implementadas
++simplesmente como parte de uma string. ::
+ 
+     sage: A = matrix(ZZ, 2, 2, range(4))
+     sage: latex(A)
+@@ -217,10 +218,10 @@
+     <html><div class="math">\newcommand{\Bold}[1]{\mathbb{#1}}\Bold{Q}</div></html>
+     sage: latex.blackboard_bold(False)
+ 
+-É possível aproveitar os recursos do TeX adicionando novas macros e
+-novos pacotes. Primeiro, macros individuais podem ser adicionadas para
+-serem usadas quando o jsMath interpreta pequenos trechos de códigos
+-TeX no Notebook. ::
++É possível aproveitar os recursos do TeX adicionando novas funções
++(macros em inglês) e novos pacotes. Primeiro, funções individuais podem
++ser adicionadas para serem usadas quando o jsMath interpreta pequenos
++trechos de códigos TeX no Notebook. ::
+ 
+     sage: latex.extra_macros()
+     ''
+@@ -436,7 +437,7 @@
+ Para uma experiência semelhante no Notebook, é necessário desabilitar
+ o processador jsMath para o código LaTeX do grafo usando a "lista de
+ comandos a serem evitados pelo jsMath". Grafos são criados usando o
+-environment ``tikzpicture``, logo essa uma boa escolha para uma string
++ambiente ``tikzpicture``, logo essa uma boa escolha para uma string
+ a ser incluída na lista que acabamos de mencionar. Agora,
+ ``view(graphs.CompleteGraph(4))`` em uma folha de trabalho deve
+ executar o pdflatex para criar um PDF e então o programa ``convert``
+@@ -486,7 +487,7 @@
+ 
+ Existem três programas disponíveis para integrar ainda mais o TeX e o
+ Sage. O primeiro é o sagetex. Uma descrição concisa do sagetex é que
+-ele é uma coleção de macros do TeX que permitem incluir em um
++ele é uma coleção de funções do TeX que permitem incluir em um
+ documento LaTeX instruções para usar o Sage para calcular vários
+ objetos, e/ou formatar objetos usando o comando ``latex()`` existente
+ no Sage. Logo, como um passo intermediário para compilar um documento
+@@ -496,7 +497,7 @@
+ sagetex para fazer cálculos com o Sage. Veja :ref:`sec-sagetex` para
+ mais informações.
+ 
+-O tex2sws começa com um documento LaTeX, mas define environments
++O tex2sws começa com um documento LaTeX, mas define ambientes
+ adicionais para inserir código em Sage. Quando processado com as
+ ferramentas adequadas, o resultado é uma folha de trabalho do Sage,
+ com conteúdo apropriadamente formatado para o jsMath e com código em
+diff --git a/doc/pt/tutorial/programming.rst b/doc/pt/tutorial/programming.rst
+--- a/doc/pt/tutorial/programming.rst
++++ b/doc/pt/tutorial/programming.rst
+@@ -66,7 +66,7 @@
+ (Em Python, ``^`` significa "ou exclusivo" e ``**`` significa
+ "exponenciação".)
+ 
+-Esse "preparsing" está implementado em ``sage/misc/interpreter.py``.)
++Esse "" está implementado em ``sage/misc/interpreter.py``.)
+ 
+ Você pode colar código tabulado com muitas linhas no Sage desde que
+ existam linhas em branco separando blocos de código (isso não é
+@@ -130,7 +130,7 @@
+ em ``$HOME/.sage/temp/hostname/pid/spyx``. Esses arquivos são
+ excluídos quando você encerra o Sage.
+ 
+-Nenhum pré-processador (preparsing) é aplicado em arquivos spyx, por
++Nenhum pré-processamento (preparsing) é aplicado em arquivos spyx, por
+ exemplo, ``1/3`` vai resultar em 0 em um arquivo spyx em vez do número
+ racional :math:`1/3`. Se ``foo`` é uma função da biblioteca Sage, para
+ usá-la em um arquivo spyx importe ``sage.all`` e use ``sage.all.foo``.
+@@ -456,10 +456,10 @@
+ Dicionários
+ ===========
+ 
+-Um dicionário (também chamado as vezes de lista associativa) é um
+-mapeamento de objetos "hashable" em objetos arbitrários. (Exemplos de
+-objetos "hashable" são strings e números; veja a documentação Python
+-em http://docs.python.org/tut/node7.html e
++Um dicionário (também chamado as vezes de lista associativa ou "hash
++table") é um mapeamento de objetos em objetos arbitrários. (Exemplos
++de objetos que admitem uma lista associativa são strings e números;
++veja a documentação Python em http://docs.python.org/tut/node7.html e
+ http://docs.python.org/lib/typesmapping.html para detalhes).
+ 
+ ::
+@@ -502,7 +502,7 @@
+ Conjuntos
+ =========
+ 
+-O Python possui um tipo set (conjuntos) nativo. O principal recurso
++O Python possui um tipo de conjuntos (set) nativo. O principal recurso
+ que ele oferece é a rápida verificação se um objeto está ou não em um
+ conjunto, juntamente com as operações comuns em conjuntos.
+ 
+diff --git a/doc/pt/tutorial/sagetex.rst b/doc/pt/tutorial/sagetex.rst
+--- a/doc/pt/tutorial/sagetex.rst
++++ b/doc/pt/tutorial/sagetex.rst
+@@ -88,14 +88,14 @@
+ que tudo que foi calculado, incluindo os gráficos, foi incluído em seu
+ documento.
+ 
+-As macros utilizadas acima devem ser fáceis de entender. Um
+-environment ``sageblock`` insere código "verbatim" (exatamente como é
+-digitado) e também executa o código quando você executa o Sage. Quando
+-você insere ``\sage{foo}``, é incluído em seu documento o resultado
+-que você obteria executando ``latex(foo)`` no Sage. Comandos para
+-fazer gráficos são um pouco mais complicados, mas em sua forma mais
+-simples, ``\sageplot{foo}`` insere a imagem que você obtêm usando
+-``foo.save('filename.eps')``.
++As funções (macros em inglês) utilizadas acima devem ser fáceis de
++entender. Um ambiente ``sageblock`` insere código "verbatim"
++(exatamente como é digitado) e também executa o código quando você
++executa o Sage. Quando você insere ``\sage{foo}``, é incluído em seu
++documento o resultado que você obteria executando ``latex(foo)`` no
++Sage. Comandos para fazer gráficos são um pouco mais complicados, mas
++em sua forma mais simples, ``\sageplot{foo}`` insere a imagem que você
++obtêm usando ``foo.save('filename.eps')``.
+ 
+ Em geral, a rotina é a seguinte:
+ 
+diff --git a/doc/pt/tutorial/tour_advanced.rst b/doc/pt/tutorial/tour_advanced.rst
+--- a/doc/pt/tutorial/tour_advanced.rst
++++ b/doc/pt/tutorial/tour_advanced.rst
+@@ -84,7 +84,7 @@
+ funcionalidade para curvas elípticas do PARI, acesso aos dados da base
+ de dados Cremona (isso requer um pacote adicional), os recursos do
+ mwrank, isto é, "2-descends" com cálculos do grupo de Mordell-Weil
+-completo, o algoritmo SEA (singla em inglês), cálculo de todas as
++completo, o algoritmo SEA (sigla em inglês), cálculo de todas as
+ isogenias, bastante código novo para curvas sobre :math:`\QQ`, e parte
+ do software "algebraic descent" de Denis Simons.
+ 
+@@ -98,7 +98,7 @@
+    .. math::  y^2+a_1xy+a_3y=x^3+a_2x^2+a_4x+a_6,
+ 
+ 
+-   onde os :math:`a_i`'s são coagidos para os parentes de :math:`a_1`.
++   onde os :math:`a_i`'s são coagidos para a família de :math:`a_1`.
+    Se todos os :math:`a_i` possuem parente :math:`\ZZ`, então eles são
+    coagidos para :math:`\QQ`.
+ 
+diff --git a/doc/pt/tutorial/tour_assignment.rst b/doc/pt/tutorial/tour_assignment.rst
+--- a/doc/pt/tutorial/tour_assignment.rst
++++ b/doc/pt/tutorial/tour_assignment.rst
+@@ -81,10 +81,9 @@
+     sage: numerical_approx(pi, prec=200)
+     3.1415926535897932384626433832795028841971693993751058209749
+ 
+-O Python é uma linguagem "dinâmicamente digitada" (dynamically typed),
+-portanto o valor referido por cada variável possui um tipo associado a
+-ele, mas uma variável pode possuir valores de qualquer tipo em
+-determinado escopo:
++O Python é uma linguagem de tipagem dinâmica, portanto o valor
++referido por cada variável possui um tipo associado a ele, mas uma
++variável pode possuir valores de qualquer tipo em determinado escopo:
+ 
+ ::
+ 
+@@ -98,9 +97,9 @@
+     sage: type(a)
+     <type 'str'>
+ 
+-A linguagem de programação C, que é "estaticamente digitada"
+-(statically typed), é muito diferente; uma variável que foi declarada
+-como int pode apenas armazenar um int em seu escopo.
++A linguagem de programação C, que é de tipagem estática , é muito
++diferente; uma variável que foi declarada como int pode apenas
++armazenar um int em seu escopo.
+ 
+ Uma potencial fonte de confusão em Python é que um inteiro literal que
+ começa com zero é tratado como um número octal, isto é, um número na
+diff --git a/doc/pt/tutorial/tour_coercion.rst b/doc/pt/tutorial/tour_coercion.rst
+--- a/doc/pt/tutorial/tour_coercion.rst
++++ b/doc/pt/tutorial/tour_coercion.rst
+@@ -3,11 +3,11 @@
+ .. _section-coercion:
+ 
+ ============================
+-Parentes, Conversão e Coação
++Famílias, Conversão e Coação
+ ============================
+ 
+ Esta seção pode parecer mais técnica do que as anteriores, mas
+-acreditamos que é importante entender o significado de parentes e
++acreditamos que é importante entender o significado de famílias e
+ coação de modo a usar anéis e outras estruturas algébricas no Sage de
+ forma efetiva e eficiente.
+ 
+@@ -25,8 +25,8 @@
+ ``__mul__``, obviamente garantindo que os axiomas de anel são
+ verificados.
+ 
+-Como o Python é uma linguagem "strongly typed" (ainda que "dynamically
+-typed"), poderia-se, pelo menos a princípio, esperar-se que fosse
++Como o Python é uma linguagem de tipagem forte (ainda que de tipagem
++dinâmica), poderia-se, pelo menos a princípio, esperar-se que fosse
+ implementado em Python uma classe para cada anel. No final das contas,
+ o Python contém um tipo ``<int>`` para os inteiros, um tipo
+ ``<float>`` para os reais, e assim por diante. Mas essa estratégia
+@@ -87,7 +87,7 @@
+     Univariate Polynomial Ring in c over Integer Ring (using NTL)
+ 
+ 
+-Parentes e Categorias
++Famílias e Categorias
+ ---------------------
+ 
+ De forma similar à hierarquia de classes em Python voltada para
+@@ -137,10 +137,9 @@
+ gerais independentemente de uma implementação específica nas
+ categorias.
+ 
+-Estruturas parentes em Sage são supostamente objetos únicos em Python.
+-Por exemplo, uma vez que um anel de polinômios sobre um certo anel
+-base e com uma certa lista de geradores é criada, o resultado é
+-arquivado:
++Estruturas da mesma família em Sage são supostamente objetos únicos em
++Python. Por exemplo, uma vez que um anel de polinômios sobre um certo anel
++base e com uma certa lista de geradores é criada, o resultado é arquivado:
+ 
+ ::
+ 
+@@ -163,7 +162,7 @@
+     sage: isinstance(M, RingElement)
+     True
+ 
+-Enquanto *parentes* são únicos, elementos iguais de um parente em Sage
++Enquanto *famílias* são únicas, elementos iguais de uma família em Sage
+ não são necessariamente idênticos. Isso contrasta com o comportamento
+ do Python para alguns (embora não todos) inteiros:
+ 
+@@ -177,7 +176,7 @@
+     False
+ 
+ É importante observar que elementos de anéis diferentes em geral não
+-podem ser distinguidos pelos seus tipos, mas sim por seus parentes:
++podem ser distinguidos pelos seus tipos, mas sim por sua família:
+ 
+ ::
+ 
+@@ -203,7 +202,7 @@
+ O leitor pode conhecer as noções de *conversão de tipo* e *coação de
+ tipo* como na linguagem C, por exemplo. Existem noções de *conversão*
+ e *coação* em Sage também. Mas as noções em Sage são centradas em
+-*parentes*, não em tipos. Então, por favor não confunda conversão de
++*família*, não em tipos. Então, por favor não confunda conversão de
+ tipo em C com conversão em Sage!
+ 
+ Aqui se encontra uma breve apresentação. Para uma descrição detalhada
+@@ -227,12 +226,12 @@
+   permitidas. O elemento neutro da multiplicação existe em todos os
+   corpos e em vários anéis, e eles devem ser todos iguais.
+ 
+-O Sage faz uma concessão. Se ``P1`` e ``P2`` são estruturas parentes e
+-``p1`` é um elemento de ``P1``, então o usuário pode explicitamente
+-perguntar por uma interpretação de ``p1`` em ``P2``. Isso pode não
+-fazer sentido em todos os casos ou não estar definido para todos os
+-elementos de ``P1``, e fica a cargo do usuário assegurar que isso faz
+-sentido. Nos referimos a isso como **conversão**:
++O Sage faz uma concessão. Se ``P1`` e ``P2`` são estruturas da mesma família
++e ``p1`` é um elemento de ``P1``, então o usuário pode explicitamente
++perguntar por uma interpretação de ``p1`` em ``P2``. Isso pode não fazer
++sentido em todos os casos ou não estar definido para todos os elementos de
++``P1``, e fica a cargo do usuário assegurar que isso faz sentido. Nos
++referimos a isso como **conversão**:
+ 
+ ::
+ 
+@@ -283,7 +282,7 @@
+     sage: R2(y)
+     y
+ 
+-Se não existir homomorfismo de anel que preserve nomes, coerção não é
++Se não existir homomorfismo de anel que preserve nomes, coação não é
+ definida. Todavia, conversão pode ainda ser possível, a saber,
+ mapeando geradores de anel de acordo com sua posição da lista de
+ geradores:
+@@ -309,7 +308,7 @@
+ Se houver coação, ela será usada para comparar elementos de anéis
+ diferentes ou fazer aritmética. Isso é frequentemente conveniente, mas
+ o usuário deve estar ciente que estender a relação ``==`` além das
+-fronteiras de parentes diferentes pode facilmente resultar em 
++fronteiras de famílias diferentes pode facilmente resultar em 
+ problemas. Por exemplo, enquanto ``==`` é supostamente uma relação de
+ equivalência sobre os elementos de *um* anel, isso não é
+ necessariamente o caso se anéis *diferentes* estão envolvidos. Por
+@@ -360,7 +359,7 @@
+     sage: 1/10^200+1/10^100 == 1/10^100
+     False
+ 
+-Quando se compara elementos de dois parentes ``P1`` e ``P2``, é
++Quando se compara elementos de duas famílias ``P1`` e ``P2``, é
+ possível que não haja coação entre os dois anéis, mas existe uma
+ escolha canônica de um parente ``P3`` de modo que tanto ``P1`` como
+ ``P2`` são coagidos em ``P3``. Nesse caso, coação vai ocorrer também.
+@@ -381,7 +380,7 @@
+ Note que a princípio o resultado deveria também fazer sentido no
+ corpo de frações de ``ZZ['x']``. Todavia, o Sage tenta escolher um
+ parente *canônico* comum que parece ser o mais natural (``QQ['x']`` no
+-nosso exemplo). Se vários potenciais parentes comuns parecem
++nosso exemplo). Se várias famílias potencialmente comuns parecem
+ igualmente naturais, o Sage *não* vai escolher um deles
+ aleatoriamente. Os mecanismos sobre os quais essa escolha se baseia é
+ explicado em um `arquivo tutorial
+@@ -401,5 +400,5 @@
+ A razão é que o Sage não escolhe um dos potenciais candidatos
+ ``QQ['x']['y']``, ``QQ['y']['x']``, ``QQ['x','y']`` ou
+ ``QQ['y','x']``, porque todas essas estruturas combinadas em pares
+-diferentes parecem ser parentes comuns naturais, e não existe escolha
++diferentes parecem ser de famílias comuns naturais, e não existe escolha
+ canônica aparente.


More information about the scm-commits mailing list