import rev14 of original Qwad

This commit is contained in:
Christopher Roy Bratusek 2012-08-21 19:28:14 +02:00
commit 5e8cf2a477
66 changed files with 18395 additions and 0 deletions

26
CHANGELOG.txt Normal file
View File

@ -0,0 +1,26 @@
CHANGELOG
--0.3--(in development)
*Updated some porject's files which still referenced wii signer
*Added application's name and organization
*Now NUS title combobox is displayed sorteed
*Fixed everyone votes channel not returning a correct titleid
*Added some IOS to the dictionary
*Now can display the data stored in a TMD file.
-- 0.2 --
Major rewrite and refactoring of code.
*Backend changed from Wii Signer to the awesome Wii.py
*Added support form downloading and packing wads from NUS
*Added statusbar
*Now the backend runs in a different thread
Known bugs:
*Title names amb some statusbar messages don't get translated
*Title dictionary is incomplete. Additionally, there may be titles in the combobox which aren't actually in the NUS.
-- 0.1.1 Now with a windows port! --
*Fixed open modes and paths in order to work in Windows
*Independization from Wii Signer, due to needed changes to the original code. Now Qwad isn't a frontend anymore.
-- 0.1 - First public version --

28
GUI/AboutQwad.py Normal file
View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
"""
Module implementing AboutQwad.
"""
from PyQt4.QtGui import QDialog
from PyQt4.QtCore import pyqtSignature
from Ui_AboutQwad import Ui_Dialog
def Version():
return "0.2+svn"
def Author():
return "ssorgatem <ssorgatem@esdebian.org>"
class AboutQwad(QDialog, Ui_Dialog):
"""
Class documentation goes here.
"""
def __init__(self, parent = None):
"""
Constructor
"""
QDialog.__init__(self, parent)
self.setupUi(self)
self.versionNumber.setText(Version())
self.AuthorName.setText(Author())

864
GUI/AboutQwad.ui Normal file
View File

@ -0,0 +1,864 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>441</width>
<height>496</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="windowIcon">
<iconset resource="../Qwad.qrc">
<normaloff>:/icons/wad.png</normaloff>:/icons/wad.png</iconset>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<widget class="QLabel" name="QwadIcon">
<property name="geometry">
<rect>
<x>150</x>
<y>0</y>
<width>131</width>
<height>131</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../Qwad.qrc">:/icons/wad.png</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
<widget class="QLabel" name="Qwad_name">
<property name="geometry">
<rect>
<x>170</x>
<y>110</y>
<width>91</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:24pt; font-weight:600;&quot;&gt;Qwad&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="Version">
<property name="geometry">
<rect>
<x>180</x>
<y>150</y>
<width>51</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Version</string>
</property>
</widget>
<widget class="QLabel" name="byAuthor">
<property name="geometry">
<rect>
<x>70</x>
<y>170</y>
<width>51</width>
<height>20</height>
</rect>
</property>
<property name="locale">
<locale language="English" country="UnitedKingdom"/>
</property>
<property name="text">
<string>Author: </string>
</property>
</widget>
<widget class="QLabel" name="versionNumber">
<property name="geometry">
<rect>
<x>230</x>
<y>150</y>
<width>131</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="AuthorName">
<property name="geometry">
<rect>
<x>120</x>
<y>170</y>
<width>311</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QTabWidget" name="abuttabs">
<property name="geometry">
<rect>
<x>10</x>
<y>200</y>
<width>421</width>
<height>281</height>
</rect>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="licensetab">
<attribute name="title">
<string>License</string>
</attribute>
<widget class="QTextEdit" name="textEdit">
<property name="geometry">
<rect>
<x>0</x>
<y>10</y>
<width>411</width>
<height>231</height>
</rect>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; GNU GENERAL PUBLIC LICENSE&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Version 3, 29 June 2007&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Copyright (C) 2007 Free Software Foundation, Inc. &amp;lt;http://fsf.org/&amp;gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Everyone is permitted to copy and distribute verbatim copies&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; of this license document, but changing it is not allowed.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Preamble&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The GNU General Public License is a free, copyleft license for&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;software and other kinds of works.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The licenses for most software and other practical works are designed&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;to take away your freedom to share and change the works. By contrast,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the GNU General Public License is intended to guarantee your freedom to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;share and change all versions of a program--to make sure it remains free&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;software for all its users. We, the Free Software Foundation, use the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;GNU General Public License for most of our software; it applies also to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;any other work released this way by its authors. You can apply it to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;your programs, too.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; When we speak of free software, we are referring to freedom, not&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;price. Our General Public Licenses are designed to make sure that you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;have the freedom to distribute copies of free software (and charge for&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;them if you wish), that you receive source code or can get it if you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;want it, that you can change the software or use pieces of it in new&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;free programs, and that you know you can do these things.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; To protect your rights, we need to prevent others from denying you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;these rights or asking you to surrender the rights. Therefore, you have&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;certain responsibilities if you distribute copies of the software, or if&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;you modify it: responsibilities to respect the freedom of others.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; For example, if you distribute copies of such a program, whether&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;gratis or for a fee, you must pass on to the recipients the same&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;freedoms that you received. You must make sure that they, too, receive&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;or can get the source code. And you must show them these terms so they&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;know their rights.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Developers that use the GNU GPL protect your rights with two steps:&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;(1) assert copyright on the software, and (2) offer you this License&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;giving you legal permission to copy, distribute and/or modify it.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; For the developers' and authors' protection, the GPL clearly explains&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;that there is no warranty for this free software. For both users' and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;authors' sake, the GPL requires that modified versions be marked as&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;changed, so that their problems will not be attributed erroneously to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;authors of previous versions.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Some devices are designed to deny users access to install or run&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;modified versions of the software inside them, although the manufacturer&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;can do so. This is fundamentally incompatible with the aim of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;protecting users' freedom to change the software. The systematic&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;pattern of such abuse occurs in the area of products for individuals to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;use, which is precisely where it is most unacceptable. Therefore, we&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;have designed this version of the GPL to prohibit the practice for those&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;products. If such problems arise substantially in other domains, we&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;stand ready to extend this provision to those domains in future versions&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;of the GPL, as needed to protect the freedom of users.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Finally, every program is threatened constantly by software patents.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;States should not allow patents to restrict development and use of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;software on general-purpose computers, but in those that do, we wish to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;avoid the special danger that patents applied to a free program could&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;make it effectively proprietary. To prevent this, the GPL assures that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;patents cannot be used to render the program non-free.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The precise terms and conditions for copying, distribution and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;modification follow.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; TERMS AND CONDITIONS&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 0. Definitions.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; &quot;This License&quot; refers to version 3 of the GNU General Public License.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; &quot;Copyright&quot; also means copyright-like laws that apply to other kinds of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;works, such as semiconductor masks.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; &quot;The Program&quot; refers to any copyrightable work licensed under this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&quot;recipients&quot; may be individuals or organizations.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; To &quot;modify&quot; a work means to copy from or adapt all or part of the work&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;in a fashion requiring copyright permission, other than the making of an&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;exact copy. The resulting work is called a &quot;modified version&quot; of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;earlier work or a work &quot;based on&quot; the earlier work.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; A &quot;covered work&quot; means either the unmodified Program or a work based&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;on the Program.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; To &quot;propagate&quot; a work means to do anything with it that, without&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;permission, would make you directly or secondarily liable for&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;infringement under applicable copyright law, except executing it on a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;computer or modifying a private copy. Propagation includes copying,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;distribution (with or without modification), making available to the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;public, and in some countries other activities as well.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; To &quot;convey&quot; a work means any kind of propagation that enables other&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;parties to make or receive copies. Mere interaction with a user through&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;a computer network, with no transfer of a copy, is not conveying.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; An interactive user interface displays &quot;Appropriate Legal Notices&quot;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;to the extent that it includes a convenient and prominently visible&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;feature that (1) displays an appropriate copyright notice, and (2)&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;tells the user that there is no warranty for the work (except to the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;extent that warranties are provided), that licensees may convey the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;work under this License, and how to view a copy of this License. If&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the interface presents a list of user commands or options, such as a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;menu, a prominent item in the list meets this criterion.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 1. Source Code.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The &quot;source code&quot; for a work means the preferred form of the work&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;for making modifications to it. &quot;Object code&quot; means any non-source&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;form of a work.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; A &quot;Standard Interface&quot; means an interface that either is an official&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;standard defined by a recognized standards body, or, in the case of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;interfaces specified for a particular programming language, one that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;is widely used among developers working in that language.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The &quot;System Libraries&quot; of an executable work include anything, other&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;than the work as a whole, that (a) is included in the normal form of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;packaging a Major Component, but which is not part of that Major&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Component, and (b) serves only to enable use of the work with that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Major Component, or to implement a Standard Interface for which an&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;implementation is available to the public in source code form. A&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&quot;Major Component&quot;, in this context, means a major essential component&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;(kernel, window system, and so on) of the specific operating system&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;(if any) on which the executable work runs, or a compiler used to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;produce the work, or an object code interpreter used to run it.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The &quot;Corresponding Source&quot; for a work in object code form means all&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the source code needed to generate, install, and (for an executable&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;work) run the object code and to modify the work, including scripts to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;control those activities. However, it does not include the work's&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;System Libraries, or general-purpose tools or generally available free&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;programs which are used unmodified in performing those activities but&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;which are not part of the work. For example, Corresponding Source&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;includes interface definition files associated with source files for&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the work, and the source code for shared libraries and dynamically&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;linked subprograms that the work is specifically designed to require,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;such as by intimate data communication or control flow between those&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;subprograms and other parts of the work.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The Corresponding Source need not include anything that users&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;can regenerate automatically from other parts of the Corresponding&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Source.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The Corresponding Source for a work in source code form is that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;same work.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 2. Basic Permissions.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; All rights granted under this License are granted for the term of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;copyright on the Program, and are irrevocable provided the stated&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;conditions are met. This License explicitly affirms your unlimited&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;permission to run the unmodified Program. The output from running a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;covered work is covered by this License only if the output, given its&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;content, constitutes a covered work. This License acknowledges your&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;rights of fair use or other equivalent, as provided by copyright law.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You may make, run and propagate covered works that you do not&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;convey, without conditions so long as your license otherwise remains&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;in force. You may convey covered works to others for the sole purpose&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;of having them make modifications exclusively for you, or provide you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;with facilities for running those works, provided that you comply with&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the terms of this License in conveying all material for which you do&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;not control copyright. Those thus making or running the covered works&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;for you must do so exclusively on your behalf, under your direction&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;and control, on terms that prohibit them from making any copies of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;your copyrighted material outside their relationship with you.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Conveying under any other circumstances is permitted solely under&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the conditions stated below. Sublicensing is not allowed; section 10&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;makes it unnecessary.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 3. Protecting Users' Legal Rights From Anti-Circumvention Law.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; No covered work shall be deemed part of an effective technological&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;measure under any applicable law fulfilling obligations under article&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;11 of the WIPO copyright treaty adopted on 20 December 1996, or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;similar laws prohibiting or restricting circumvention of such&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;measures.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; When you convey a covered work, you waive any legal power to forbid&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;circumvention of technological measures to the extent such circumvention&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;is effected by exercising rights under this License with respect to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the covered work, and you disclaim any intention to limit operation or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;modification of the work as a means of enforcing, against the work's&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;users, your or third parties' legal rights to forbid circumvention of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;technological measures.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 4. Conveying Verbatim Copies.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You may convey verbatim copies of the Program's source code as you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;receive it, in any medium, provided that you conspicuously and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;appropriately publish on each copy an appropriate copyright notice;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;keep intact all notices stating that this License and any&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;non-permissive terms added in accord with section 7 apply to the code;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;keep intact all notices of the absence of any warranty; and give all&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;recipients a copy of this License along with the Program.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You may charge any price or no price for each copy that you convey,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;and you may offer support or warranty protection for a fee.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 5. Conveying Modified Source Versions.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You may convey a work based on the Program, or the modifications to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;produce it from the Program, in the form of source code under the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;terms of section 4, provided that you also meet all of these conditions:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; a) The work must carry prominent notices stating that you modified&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; it, and giving a relevant date.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; b) The work must carry prominent notices stating that it is&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; released under this License and any conditions added under section&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 7. This requirement modifies the requirement in section 4 to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; &quot;keep intact all notices&quot;.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; c) You must license the entire work, as a whole, under this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; License to anyone who comes into possession of a copy. This&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; License will therefore apply, along with any applicable section 7&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; additional terms, to the whole of the work, and all its parts,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; regardless of how they are packaged. This License gives no&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; permission to license the work in any other way, but it does not&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; invalidate such permission if you have separately received it.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; d) If the work has interactive user interfaces, each must display&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Appropriate Legal Notices; however, if the Program has interactive&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; interfaces that do not display Appropriate Legal Notices, your&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; work need not make them do so.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; A compilation of a covered work with other separate and independent&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;works, which are not by their nature extensions of the covered work,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;and which are not combined with it such as to form a larger program,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;in or on a volume of a storage or distribution medium, is called an&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&quot;aggregate&quot; if the compilation and its resulting copyright are not&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;used to limit the access or legal rights of the compilation's users&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;beyond what the individual works permit. Inclusion of a covered work&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;in an aggregate does not cause this License to apply to the other&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;parts of the aggregate.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 6. Conveying Non-Source Forms.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You may convey a covered work in object code form under the terms&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;of sections 4 and 5, provided that you also convey the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;machine-readable Corresponding Source under the terms of this License,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;in one of these ways:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; a) Convey the object code in, or embodied in, a physical product&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; (including a physical distribution medium), accompanied by the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Corresponding Source fixed on a durable physical medium&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; customarily used for software interchange.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; b) Convey the object code in, or embodied in, a physical product&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; (including a physical distribution medium), accompanied by a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; written offer, valid for at least three years and valid for as&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; long as you offer spare parts or customer support for that product&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; model, to give anyone who possesses the object code either (1) a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; copy of the Corresponding Source for all the software in the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; product that is covered by this License, on a durable physical&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; medium customarily used for software interchange, for a price no&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; more than your reasonable cost of physically performing this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; conveying of source, or (2) access to copy the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Corresponding Source from a network server at no charge.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; c) Convey individual copies of the object code with a copy of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; written offer to provide the Corresponding Source. This&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; alternative is allowed only occasionally and noncommercially, and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; only if you received the object code with such an offer, in accord&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; with subsection 6b.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; d) Convey the object code by offering access from a designated&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; place (gratis or for a charge), and offer equivalent access to the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Corresponding Source in the same way through the same place at no&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; further charge. You need not require recipients to copy the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Corresponding Source along with the object code. If the place to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; copy the object code is a network server, the Corresponding Source&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; may be on a different server (operated by you or a third party)&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; that supports equivalent copying facilities, provided you maintain&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; clear directions next to the object code saying where to find the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Corresponding Source. Regardless of what server hosts the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Corresponding Source, you remain obligated to ensure that it is&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; available for as long as needed to satisfy these requirements.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; e) Convey the object code using peer-to-peer transmission, provided&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; you inform other peers where the object code and Corresponding&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Source of the work are being offered to the general public at no&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; charge under subsection 6d.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; A separable portion of the object code, whose source code is excluded&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;from the Corresponding Source as a System Library, need not be&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;included in conveying the object code work.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;tangible personal property which is normally used for personal, family,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;or household purposes, or (2) anything designed or sold for incorporation&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;into a dwelling. In determining whether a product is a consumer product,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;doubtful cases shall be resolved in favor of coverage. For a particular&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;product received by a particular user, &quot;normally used&quot; refers to a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;typical or common use of that class of product, regardless of the status&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;of the particular user or of the way in which the particular user&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;actually uses, or expects or is expected to use, the product. A product&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;is a consumer product regardless of whether the product has substantial&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;commercial, industrial or non-consumer uses, unless such uses represent&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the only significant mode of use of the product.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; &quot;Installation Information&quot; for a User Product means any methods,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;procedures, authorization keys, or other information required to install&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;and execute modified versions of a covered work in that User Product from&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;a modified version of its Corresponding Source. The information must&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;suffice to ensure that the continued functioning of the modified object&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;code is in no case prevented or interfered with solely because&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;modification has been made.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If you convey an object code work under this section in, or with, or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;specifically for use in, a User Product, and the conveying occurs as&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;part of a transaction in which the right of possession and use of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;User Product is transferred to the recipient in perpetuity or for a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;fixed term (regardless of how the transaction is characterized), the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Corresponding Source conveyed under this section must be accompanied&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;by the Installation Information. But this requirement does not apply&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;if neither you nor any third party retains the ability to install&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;modified object code on the User Product (for example, the work has&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;been installed in ROM).&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The requirement to provide Installation Information does not include a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;requirement to continue to provide support service, warranty, or updates&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;for a work that has been modified or installed by the recipient, or for&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the User Product in which it has been modified or installed. Access to a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;network may be denied when the modification itself materially and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;adversely affects the operation of the network or violates the rules and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;protocols for communication across the network.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Corresponding Source conveyed, and Installation Information provided,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;in accord with this section must be in a format that is publicly&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;documented (and with an implementation available to the public in&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;source code form), and must require no special password or key for&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;unpacking, reading or copying.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 7. Additional Terms.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; &quot;Additional permissions&quot; are terms that supplement the terms of this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;License by making exceptions from one or more of its conditions.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Additional permissions that are applicable to the entire Program shall&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;be treated as though they were included in this License, to the extent&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;that they are valid under applicable law. If additional permissions&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;apply only to part of the Program, that part may be used separately&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;under those permissions, but the entire Program remains governed by&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;this License without regard to the additional permissions.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; When you convey a copy of a covered work, you may at your option&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;remove any additional permissions from that copy, or from any part of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;it. (Additional permissions may be written to require their own&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;removal in certain cases when you modify the work.) You may place&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;additional permissions on material, added by you to a covered work,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;for which you have or can give appropriate copyright permission.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Notwithstanding any other provision of this License, for material you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;add to a covered work, you may (if authorized by the copyright holders of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;that material) supplement the terms of this License with terms:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; a) Disclaiming warranty or limiting liability differently from the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; terms of sections 15 and 16 of this License; or&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; b) Requiring preservation of specified reasonable legal notices or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; author attributions in that material or in the Appropriate Legal&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Notices displayed by works containing it; or&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; c) Prohibiting misrepresentation of the origin of that material, or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; requiring that modified versions of such material be marked in&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; reasonable ways as different from the original version; or&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; d) Limiting the use for publicity purposes of names of licensors or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; authors of the material; or&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; e) Declining to grant rights under trademark law for use of some&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; trade names, trademarks, or service marks; or&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; f) Requiring indemnification of licensors and authors of that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; material by anyone who conveys the material (or modified versions of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; it) with contractual assumptions of liability to the recipient, for&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; any liability that these contractual assumptions directly impose on&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; those licensors and authors.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; All other non-permissive additional terms are considered &quot;further&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;restrictions&quot; within the meaning of section 10. If the Program as you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;received it, or any part of it, contains a notice stating that it is&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;governed by this License along with a term that is a further&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;restriction, you may remove that term. If a license document contains&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;a further restriction but permits relicensing or conveying under this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;License, you may add to a covered work material governed by the terms&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;of that license document, provided that the further restriction does&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;not survive such relicensing or conveying.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If you add terms to a covered work in accord with this section, you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;must place, in the relevant source files, a statement of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;additional terms that apply to those files, or a notice indicating&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;where to find the applicable terms.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Additional terms, permissive or non-permissive, may be stated in the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;form of a separately written license, or stated as exceptions;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the above requirements apply either way.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 8. Termination.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You may not propagate or modify a covered work except as expressly&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;provided under this License. Any attempt otherwise to propagate or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;modify it is void, and will automatically terminate your rights under&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;this License (including any patent licenses granted under the third&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;paragraph of section 11).&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; However, if you cease all violation of this License, then your&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;license from a particular copyright holder is reinstated (a)&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;provisionally, unless and until the copyright holder explicitly and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;finally terminates your license, and (b) permanently, if the copyright&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;holder fails to notify you of the violation by some reasonable means&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;prior to 60 days after the cessation.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Moreover, your license from a particular copyright holder is&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;reinstated permanently if the copyright holder notifies you of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;violation by some reasonable means, this is the first time you have&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;received notice of violation of this License (for any work) from that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;copyright holder, and you cure the violation prior to 30 days after&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;your receipt of the notice.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Termination of your rights under this section does not terminate the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;licenses of parties who have received copies or rights from you under&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;this License. If your rights have been terminated and not permanently&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;reinstated, you do not qualify to receive new licenses for the same&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;material under section 10.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 9. Acceptance Not Required for Having Copies.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You are not required to accept this License in order to receive or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;run a copy of the Program. Ancillary propagation of a covered work&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;occurring solely as a consequence of using peer-to-peer transmission&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;to receive a copy likewise does not require acceptance. However,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;nothing other than this License grants you permission to propagate or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;modify any covered work. These actions infringe copyright if you do&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;not accept this License. Therefore, by modifying or propagating a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;covered work, you indicate your acceptance of this License to do so.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 10. Automatic Licensing of Downstream Recipients.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Each time you convey a covered work, the recipient automatically&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;receives a license from the original licensors, to run, modify and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;propagate that work, subject to this License. You are not responsible&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;for enforcing compliance by third parties with this License.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; An &quot;entity transaction&quot; is a transaction transferring control of an&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;organization, or substantially all assets of one, or subdividing an&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;organization, or merging organizations. If propagation of a covered&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;work results from an entity transaction, each party to that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;transaction who receives a copy of the work also receives whatever&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;licenses to the work the party's predecessor in interest had or could&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;give under the previous paragraph, plus a right to possession of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Corresponding Source of the work from the predecessor in interest, if&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the predecessor has it or can get it with reasonable efforts.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You may not impose any further restrictions on the exercise of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;rights granted or affirmed under this License. For example, you may&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;not impose a license fee, royalty, or other charge for exercise of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;rights granted under this License, and you may not initiate litigation&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;(including a cross-claim or counterclaim in a lawsuit) alleging that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;any patent claim is infringed by making, using, selling, offering for&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;sale, or importing the Program or any portion of it.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 11. Patents.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; A &quot;contributor&quot; is a copyright holder who authorizes use under this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;License of the Program or a work on which the Program is based. The&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;work thus licensed is called the contributor's &quot;contributor version&quot;.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; A contributor's &quot;essential patent claims&quot; are all patent claims&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;owned or controlled by the contributor, whether already acquired or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;hereafter acquired, that would be infringed by some manner, permitted&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;by this License, of making, using, or selling its contributor version,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;but do not include claims that would be infringed only as a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;consequence of further modification of the contributor version. For&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;purposes of this definition, &quot;control&quot; includes the right to grant&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;patent sublicenses in a manner consistent with the requirements of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;this License.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Each contributor grants you a non-exclusive, worldwide, royalty-free&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;patent license under the contributor's essential patent claims, to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;make, use, sell, offer for sale, import and otherwise run, modify and&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;propagate the contents of its contributor version.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; In the following three paragraphs, a &quot;patent license&quot; is any express&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;agreement or commitment, however denominated, not to enforce a patent&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;(such as an express permission to practice a patent or covenant not to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;sue for patent infringement). To &quot;grant&quot; such a patent license to a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;party means to make such an agreement or commitment not to enforce a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;patent against the party.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If you convey a covered work, knowingly relying on a patent license,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;and the Corresponding Source of the work is not available for anyone&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;to copy, free of charge and under the terms of this License, through a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;publicly available network server or other readily accessible means,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;then you must either (1) cause the Corresponding Source to be so&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;available, or (2) arrange to deprive yourself of the benefit of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;patent license for this particular work, or (3) arrange, in a manner&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;consistent with the requirements of this License, to extend the patent&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;license to downstream recipients. &quot;Knowingly relying&quot; means you have&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;actual knowledge that, but for the patent license, your conveying the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;covered work in a country, or your recipient's use of the covered work&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;in a country, would infringe one or more identifiable patents in that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;country that you have reason to believe are valid.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If, pursuant to or in connection with a single transaction or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;arrangement, you convey, or propagate by procuring conveyance of, a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;covered work, and grant a patent license to some of the parties&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;receiving the covered work authorizing them to use, propagate, modify&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;or convey a specific copy of the covered work, then the patent license&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;you grant is automatically extended to all recipients of the covered&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;work and works based on it.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; A patent license is &quot;discriminatory&quot; if it does not include within&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the scope of its coverage, prohibits the exercise of, or is&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;conditioned on the non-exercise of one or more of the rights that are&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;specifically granted under this License. You may not convey a covered&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;work if you are a party to an arrangement with a third party that is&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;in the business of distributing software, under which you make payment&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;to the third party based on the extent of your activity of conveying&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the work, and under which the third party grants, to any of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;parties who would receive the covered work from you, a discriminatory&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;patent license (a) in connection with copies of the covered work&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;conveyed by you (or copies made from those copies), or (b) primarily&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;for and in connection with specific products or compilations that&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;contain the covered work, unless you entered into that arrangement,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;or that patent license was granted, prior to 28 March 2007.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Nothing in this License shall be construed as excluding or limiting&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;any implied license or other defenses to infringement that may&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;otherwise be available to you under applicable patent law.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 12. No Surrender of Others' Freedom.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If conditions are imposed on you (whether by court order, agreement or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;otherwise) that contradict the conditions of this License, they do not&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;excuse you from the conditions of this License. If you cannot convey a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;covered work so as to satisfy simultaneously your obligations under this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;License and any other pertinent obligations, then as a consequence you may&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;not convey it at all. For example, if you agree to terms that obligate you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;to collect a royalty for further conveying from those to whom you convey&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the Program, the only way you could satisfy both those terms and this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;License would be to refrain entirely from conveying the Program.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 13. Use with the GNU Affero General Public License.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Notwithstanding any other provision of this License, you have&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;permission to link or combine any covered work with a work licensed&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;under version 3 of the GNU Affero General Public License into a single&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;combined work, and to convey the resulting work. The terms of this&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;License will continue to apply to the part which is the covered work,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;but the special requirements of the GNU Affero General Public License,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;section 13, concerning interaction through a network will apply to the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;combination as such.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 14. Revised Versions of this License.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The Free Software Foundation may publish revised and/or new versions of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the GNU General Public License from time to time. Such new versions will&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;be similar in spirit to the present version, but may differ in detail to&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;address new problems or concerns.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Each version is given a distinguishing version number. If the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Program specifies that a certain numbered version of the GNU General&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Public License &quot;or any later version&quot; applies to it, you have the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;option of following the terms and conditions either of that numbered&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;version or of any later version published by the Free Software&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Foundation. If the Program does not specify a version number of the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;GNU General Public License, you may choose any version ever published&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;by the Free Software Foundation.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If the Program specifies that a proxy can decide which future&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;versions of the GNU General Public License can be used, that proxy's&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;public statement of acceptance of a version permanently authorizes you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;to choose that version for the Program.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Later license versions may give you additional or different&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;permissions. However, no additional obligations are imposed on any&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;author or copyright holder as a result of your choosing to follow a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;later version.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 15. Disclaimer of Warranty.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;ALL NECESSARY SERVICING, REPAIR OR CORRECTION.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 16. Limitation of Liability.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;SUCH DAMAGES.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 17. Interpretation of Sections 15 and 16.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If the disclaimer of warranty and limitation of liability provided&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;above cannot be given local legal effect according to their terms,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;reviewing courts shall apply local law that most closely approximates&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;an absolute waiver of all civil liability in connection with the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Program, unless a warranty or assumption of liability accompanies a&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;copy of the Program in return for a fee.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; END OF TERMS AND CONDITIONS&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; How to Apply These Terms to Your New Programs&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If you develop a new program, and you want it to be of the greatest&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;possible use to the public, the best way to achieve this is to make it&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;free software which everyone can redistribute and change under these terms.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; To do so, attach the following notices to the program. It is safest&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;to attach them to the start of each source file to most effectively&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;state the exclusion of warranty; and each file should have at least&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the &quot;copyright&quot; line and a pointer to where the full notice is found.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; &amp;lt;one line to give the program's name and a brief idea of what it does.&amp;gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Copyright (C) &amp;lt;year&amp;gt; &amp;lt;name of author&amp;gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; This program is free software: you can redistribute it and/or modify&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; it under the terms of the GNU General Public License as published by&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; the Free Software Foundation, either version 3 of the License, or&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; (at your option) any later version.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; This program is distributed in the hope that it will be useful,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; GNU General Public License for more details.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You should have received a copy of the GNU General Public License&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; along with this program. If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Also add information on how to contact you by electronic and paper mail.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; If the program does terminal interaction, make it output a short&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;notice like this when it starts in an interactive mode:&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; &amp;lt;program&amp;gt; Copyright (C) &amp;lt;year&amp;gt; &amp;lt;name of author&amp;gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; This is free software, and you are welcome to redistribute it&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; under certain conditions; type `show c' for details.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The hypothetical commands `show w' and `show c' should show the appropriate&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;parts of the General Public License. Of course, your program's commands&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;might be different; for a GUI interface, you would use an &quot;about box&quot;.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; You should also get your employer (if you work as a programmer) or school,&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;if any, to sign a &quot;copyright disclaimer&quot; for the program, if necessary.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;For more information on this, and how to apply and follow the GNU GPL, see&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; The GNU General Public License does not permit incorporating your program&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;into proprietary programs. If your program is a subroutine library, you&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;may consider it more useful to permit linking proprietary applications with&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;the library. If this is what you want to do, use the GNU Lesser General&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Public License instead of this License. But first, please read&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&amp;lt;http://www.gnu.org/philosophy/why-not-lgpl.html&amp;gt;.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="acceptRichText">
<bool>false</bool>
</property>
</widget>
</widget>
<widget class="QWidget" name="thankstab">
<attribute name="title">
<string>Thanks</string>
</attribute>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>391</width>
<height>121</height>
</rect>
</property>
<property name="text">
<string>Thanks to Wii.py team: Xuzz, SquidMan, megazig, TheLemonMan, |Omega, and Matt_P. Qwad is only a frontend for their unbelievably awesome framework.</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</widget>
</widget>
</widget>
<resources>
<include location="../Qwad.qrc"/>
</resources>
<connections/>
</ui>

767
GUI/Ui_AboutQwad.py Normal file
View File

@ -0,0 +1,767 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '/home/ssorgatem/Documents/python/Qwad/GUI/AboutQwad.ui'
#
# Created: Sat Jul 25 02:02:44 2009
# by: PyQt4 UI code generator 4.4.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(441, 496)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/icons/wad.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
Dialog.setWindowIcon(icon)
self.QwadIcon = QtGui.QLabel(Dialog)
self.QwadIcon.setGeometry(QtCore.QRect(150, 0, 131, 131))
self.QwadIcon.setPixmap(QtGui.QPixmap(":/icons/wad.png"))
self.QwadIcon.setScaledContents(False)
self.QwadIcon.setObjectName("QwadIcon")
self.Qwad_name = QtGui.QLabel(Dialog)
self.Qwad_name.setGeometry(QtCore.QRect(170, 110, 91, 51))
self.Qwad_name.setObjectName("Qwad_name")
self.Version = QtGui.QLabel(Dialog)
self.Version.setGeometry(QtCore.QRect(180, 150, 51, 21))
self.Version.setObjectName("Version")
self.byAuthor = QtGui.QLabel(Dialog)
self.byAuthor.setGeometry(QtCore.QRect(70, 170, 51, 20))
self.byAuthor.setObjectName("byAuthor")
self.versionNumber = QtGui.QLabel(Dialog)
self.versionNumber.setGeometry(QtCore.QRect(230, 150, 131, 21))
self.versionNumber.setObjectName("versionNumber")
self.AuthorName = QtGui.QLabel(Dialog)
self.AuthorName.setGeometry(QtCore.QRect(120, 170, 311, 20))
self.AuthorName.setObjectName("AuthorName")
self.abuttabs = QtGui.QTabWidget(Dialog)
self.abuttabs.setGeometry(QtCore.QRect(10, 200, 421, 281))
self.abuttabs.setObjectName("abuttabs")
self.licensetab = QtGui.QWidget()
self.licensetab.setObjectName("licensetab")
self.textEdit = QtGui.QTextEdit(self.licensetab)
self.textEdit.setGeometry(QtCore.QRect(0, 10, 411, 231))
self.textEdit.setUndoRedoEnabled(False)
self.textEdit.setReadOnly(True)
self.textEdit.setAcceptRichText(False)
self.textEdit.setObjectName("textEdit")
self.abuttabs.addTab(self.licensetab, "")
self.thankstab = QtGui.QWidget()
self.thankstab.setObjectName("thankstab")
self.label = QtGui.QLabel(self.thankstab)
self.label.setGeometry(QtCore.QRect(10, 10, 391, 121))
self.label.setScaledContents(True)
self.label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.label.setWordWrap(True)
self.label.setObjectName("label")
self.abuttabs.addTab(self.thankstab, "")
self.retranslateUi(Dialog)
self.abuttabs.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.Qwad_name.setText(QtGui.QApplication.translate("Dialog", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'DejaVu Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:24pt; font-weight:600;\">Qwad</span></p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
self.Version.setText(QtGui.QApplication.translate("Dialog", "Version", None, QtGui.QApplication.UnicodeUTF8))
self.byAuthor.setText(QtGui.QApplication.translate("Dialog", "Author: ", None, QtGui.QApplication.UnicodeUTF8))
self.textEdit.setHtml(QtGui.QApplication.translate("Dialog", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'DejaVu Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> GNU GENERAL PUBLIC LICENSE</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Version 3, 29 June 2007</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Everyone is permitted to copy and distribute verbatim copies</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> of this license document, but changing it is not allowed.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Preamble</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The GNU General Public License is a free, copyleft license for</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">software and other kinds of works.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The licenses for most software and other practical works are designed</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">to take away your freedom to share and change the works. By contrast,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the GNU General Public License is intended to guarantee your freedom to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">share and change all versions of a program--to make sure it remains free</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">software for all its users. We, the Free Software Foundation, use the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">GNU General Public License for most of our software; it applies also to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">any other work released this way by its authors. You can apply it to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">your programs, too.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> When we speak of free software, we are referring to freedom, not</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">price. Our General Public Licenses are designed to make sure that you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">have the freedom to distribute copies of free software (and charge for</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">them if you wish), that you receive source code or can get it if you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">want it, that you can change the software or use pieces of it in new</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">free programs, and that you know you can do these things.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> To protect your rights, we need to prevent others from denying you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">these rights or asking you to surrender the rights. Therefore, you have</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">certain responsibilities if you distribute copies of the software, or if</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">you modify it: responsibilities to respect the freedom of others.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> For example, if you distribute copies of such a program, whether</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">gratis or for a fee, you must pass on to the recipients the same</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">freedoms that you received. You must make sure that they, too, receive</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">or can get the source code. And you must show them these terms so they</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">know their rights.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Developers that use the GNU GPL protect your rights with two steps:</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">(1) assert copyright on the software, and (2) offer you this License</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">giving you legal permission to copy, distribute and/or modify it.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> For the developers\' and authors\' protection, the GPL clearly explains</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">that there is no warranty for this free software. For both users\' and</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">authors\' sake, the GPL requires that modified versions be marked as</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">changed, so that their problems will not be attributed erroneously to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">authors of previous versions.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Some devices are designed to deny users access to install or run</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">modified versions of the software inside them, although the manufacturer</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">can do so. This is fundamentally incompatible with the aim of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">protecting users\' freedom to change the software. The systematic</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">pattern of such abuse occurs in the area of products for individuals to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">use, which is precisely where it is most unacceptable. Therefore, we</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">have designed this version of the GPL to prohibit the practice for those</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">products. If such problems arise substantially in other domains, we</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">stand ready to extend this provision to those domains in future versions</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">of the GPL, as needed to protect the freedom of users.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Finally, every program is threatened constantly by software patents.</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">States should not allow patents to restrict development and use of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">software on general-purpose computers, but in those that do, we wish to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">avoid the special danger that patents applied to a free program could</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">make it effectively proprietary. To prevent this, the GPL assures that</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">patents cannot be used to render the program non-free.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The precise terms and conditions for copying, distribution and</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">modification follow.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> TERMS AND CONDITIONS</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 0. Definitions.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> \"This License\" refers to version 3 of the GNU General Public License.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> \"Copyright\" also means copyright-like laws that apply to other kinds of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">works, such as semiconductor masks.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> \"The Program\" refers to any copyrightable work licensed under this</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">License. Each licensee is addressed as \"you\". \"Licensees\" and</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">\"recipients\" may be individuals or organizations.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> To \"modify\" a work means to copy from or adapt all or part of the work</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">in a fashion requiring copyright permission, other than the making of an</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">exact copy. The resulting work is called a \"modified version\" of the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">earlier work or a work \"based on\" the earlier work.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> A \"covered work\" means either the unmodified Program or a work based</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">on the Program.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> To \"propagate\" a work means to do anything with it that, without</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">permission, would make you directly or secondarily liable for</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">infringement under applicable copyright law, except executing it on a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">computer or modifying a private copy. Propagation includes copying,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">distribution (with or without modification), making available to the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">public, and in some countries other activities as well.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> To \"convey\" a work means any kind of propagation that enables other</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">parties to make or receive copies. Mere interaction with a user through</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">a computer network, with no transfer of a copy, is not conveying.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> An interactive user interface displays \"Appropriate Legal Notices\"</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">to the extent that it includes a convenient and prominently visible</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">feature that (1) displays an appropriate copyright notice, and (2)</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">tells the user that there is no warranty for the work (except to the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">extent that warranties are provided), that licensees may convey the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">work under this License, and how to view a copy of this License. If</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the interface presents a list of user commands or options, such as a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">menu, a prominent item in the list meets this criterion.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 1. Source Code.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The \"source code\" for a work means the preferred form of the work</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">for making modifications to it. \"Object code\" means any non-source</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">form of a work.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> A \"Standard Interface\" means an interface that either is an official</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">standard defined by a recognized standards body, or, in the case of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">interfaces specified for a particular programming language, one that</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">is widely used among developers working in that language.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The \"System Libraries\" of an executable work include anything, other</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">than the work as a whole, that (a) is included in the normal form of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">packaging a Major Component, but which is not part of that Major</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Component, and (b) serves only to enable use of the work with that</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Major Component, or to implement a Standard Interface for which an</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">implementation is available to the public in source code form. A</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">\"Major Component\", in this context, means a major essential component</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">(kernel, window system, and so on) of the specific operating system</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">(if any) on which the executable work runs, or a compiler used to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">produce the work, or an object code interpreter used to run it.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The \"Corresponding Source\" for a work in object code form means all</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the source code needed to generate, install, and (for an executable</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">work) run the object code and to modify the work, including scripts to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">control those activities. However, it does not include the work\'s</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">System Libraries, or general-purpose tools or generally available free</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">programs which are used unmodified in performing those activities but</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">which are not part of the work. For example, Corresponding Source</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">includes interface definition files associated with source files for</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the work, and the source code for shared libraries and dynamically</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">linked subprograms that the work is specifically designed to require,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">such as by intimate data communication or control flow between those</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">subprograms and other parts of the work.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The Corresponding Source need not include anything that users</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">can regenerate automatically from other parts of the Corresponding</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Source.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The Corresponding Source for a work in source code form is that</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">same work.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 2. Basic Permissions.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> All rights granted under this License are granted for the term of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">copyright on the Program, and are irrevocable provided the stated</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">conditions are met. This License explicitly affirms your unlimited</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">permission to run the unmodified Program. The output from running a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">covered work is covered by this License only if the output, given its</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">content, constitutes a covered work. This License acknowledges your</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">rights of fair use or other equivalent, as provided by copyright law.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> You may make, run and propagate covered works that you do not</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">convey, without conditions so long as your license otherwise remains</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">in force. You may convey covered works to others for the sole purpose</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">of having them make modifications exclusively for you, or provide you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">with facilities for running those works, provided that you comply with</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the terms of this License in conveying all material for which you do</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">not control copyright. Those thus making or running the covered works</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">for you must do so exclusively on your behalf, under your direction</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">and control, on terms that prohibit them from making any copies of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">your copyrighted material outside their relationship with you.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Conveying under any other circumstances is permitted solely under</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the conditions stated below. Sublicensing is not allowed; section 10</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">makes it unnecessary.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 3. Protecting Users\' Legal Rights From Anti-Circumvention Law.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> No covered work shall be deemed part of an effective technological</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">measure under any applicable law fulfilling obligations under article</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">11 of the WIPO copyright treaty adopted on 20 December 1996, or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">similar laws prohibiting or restricting circumvention of such</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">measures.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> When you convey a covered work, you waive any legal power to forbid</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">circumvention of technological measures to the extent such circumvention</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">is effected by exercising rights under this License with respect to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the covered work, and you disclaim any intention to limit operation or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">modification of the work as a means of enforcing, against the work\'s</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">users, your or third parties\' legal rights to forbid circumvention of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">technological measures.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 4. Conveying Verbatim Copies.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> You may convey verbatim copies of the Program\'s source code as you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">receive it, in any medium, provided that you conspicuously and</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">appropriately publish on each copy an appropriate copyright notice;</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">keep intact all notices stating that this License and any</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">non-permissive terms added in accord with section 7 apply to the code;</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">keep intact all notices of the absence of any warranty; and give all</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">recipients a copy of this License along with the Program.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> You may charge any price or no price for each copy that you convey,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">and you may offer support or warranty protection for a fee.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 5. Conveying Modified Source Versions.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> You may convey a work based on the Program, or the modifications to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">produce it from the Program, in the form of source code under the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">terms of section 4, provided that you also meet all of these conditions:</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> a) The work must carry prominent notices stating that you modified</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> it, and giving a relevant date.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> b) The work must carry prominent notices stating that it is</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> released under this License and any conditions added under section</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 7. This requirement modifies the requirement in section 4 to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> \"keep intact all notices\".</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> c) You must license the entire work, as a whole, under this</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> License to anyone who comes into possession of a copy. This</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> License will therefore apply, along with any applicable section 7</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> additional terms, to the whole of the work, and all its parts,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> regardless of how they are packaged. This License gives no</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> permission to license the work in any other way, but it does not</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> invalidate such permission if you have separately received it.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> d) If the work has interactive user interfaces, each must display</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Appropriate Legal Notices; however, if the Program has interactive</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> interfaces that do not display Appropriate Legal Notices, your</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> work need not make them do so.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> A compilation of a covered work with other separate and independent</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">works, which are not by their nature extensions of the covered work,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">and which are not combined with it such as to form a larger program,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">in or on a volume of a storage or distribution medium, is called an</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">\"aggregate\" if the compilation and its resulting copyright are not</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">used to limit the access or legal rights of the compilation\'s users</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">beyond what the individual works permit. Inclusion of a covered work</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">in an aggregate does not cause this License to apply to the other</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">parts of the aggregate.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 6. Conveying Non-Source Forms.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> You may convey a covered work in object code form under the terms</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">of sections 4 and 5, provided that you also convey the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">machine-readable Corresponding Source under the terms of this License,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">in one of these ways:</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> a) Convey the object code in, or embodied in, a physical product</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> (including a physical distribution medium), accompanied by the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Corresponding Source fixed on a durable physical medium</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> customarily used for software interchange.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> b) Convey the object code in, or embodied in, a physical product</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> (including a physical distribution medium), accompanied by a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> written offer, valid for at least three years and valid for as</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> long as you offer spare parts or customer support for that product</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> model, to give anyone who possesses the object code either (1) a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> copy of the Corresponding Source for all the software in the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> product that is covered by this License, on a durable physical</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> medium customarily used for software interchange, for a price no</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> more than your reasonable cost of physically performing this</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> conveying of source, or (2) access to copy the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Corresponding Source from a network server at no charge.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> c) Convey individual copies of the object code with a copy of the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> written offer to provide the Corresponding Source. This</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> alternative is allowed only occasionally and noncommercially, and</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> only if you received the object code with such an offer, in accord</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> with subsection 6b.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> d) Convey the object code by offering access from a designated</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> place (gratis or for a charge), and offer equivalent access to the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Corresponding Source in the same way through the same place at no</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> further charge. You need not require recipients to copy the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Corresponding Source along with the object code. If the place to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> copy the object code is a network server, the Corresponding Source</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> may be on a different server (operated by you or a third party)</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> that supports equivalent copying facilities, provided you maintain</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> clear directions next to the object code saying where to find the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Corresponding Source. Regardless of what server hosts the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Corresponding Source, you remain obligated to ensure that it is</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> available for as long as needed to satisfy these requirements.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> e) Convey the object code using peer-to-peer transmission, provided</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> you inform other peers where the object code and Corresponding</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Source of the work are being offered to the general public at no</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> charge under subsection 6d.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> A separable portion of the object code, whose source code is excluded</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">from the Corresponding Source as a System Library, need not be</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">included in conveying the object code work.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> A \"User Product\" is either (1) a \"consumer product\", which means any</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">tangible personal property which is normally used for personal, family,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">or household purposes, or (2) anything designed or sold for incorporation</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">into a dwelling. In determining whether a product is a consumer product,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">doubtful cases shall be resolved in favor of coverage. For a particular</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">product received by a particular user, \"normally used\" refers to a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">typical or common use of that class of product, regardless of the status</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">of the particular user or of the way in which the particular user</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">actually uses, or expects or is expected to use, the product. A product</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">is a consumer product regardless of whether the product has substantial</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">commercial, industrial or non-consumer uses, unless such uses represent</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the only significant mode of use of the product.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> \"Installation Information\" for a User Product means any methods,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">procedures, authorization keys, or other information required to install</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">and execute modified versions of a covered work in that User Product from</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">a modified version of its Corresponding Source. The information must</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">suffice to ensure that the continued functioning of the modified object</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">code is in no case prevented or interfered with solely because</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">modification has been made.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> If you convey an object code work under this section in, or with, or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">specifically for use in, a User Product, and the conveying occurs as</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">part of a transaction in which the right of possession and use of the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">User Product is transferred to the recipient in perpetuity or for a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">fixed term (regardless of how the transaction is characterized), the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Corresponding Source conveyed under this section must be accompanied</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">by the Installation Information. But this requirement does not apply</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">if neither you nor any third party retains the ability to install</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">modified object code on the User Product (for example, the work has</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">been installed in ROM).</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The requirement to provide Installation Information does not include a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">requirement to continue to provide support service, warranty, or updates</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">for a work that has been modified or installed by the recipient, or for</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the User Product in which it has been modified or installed. Access to a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">network may be denied when the modification itself materially and</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">adversely affects the operation of the network or violates the rules and</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">protocols for communication across the network.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Corresponding Source conveyed, and Installation Information provided,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">in accord with this section must be in a format that is publicly</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">documented (and with an implementation available to the public in</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">source code form), and must require no special password or key for</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">unpacking, reading or copying.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 7. Additional Terms.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> \"Additional permissions\" are terms that supplement the terms of this</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">License by making exceptions from one or more of its conditions.</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Additional permissions that are applicable to the entire Program shall</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">be treated as though they were included in this License, to the extent</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">that they are valid under applicable law. If additional permissions</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">apply only to part of the Program, that part may be used separately</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">under those permissions, but the entire Program remains governed by</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">this License without regard to the additional permissions.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> When you convey a copy of a covered work, you may at your option</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">remove any additional permissions from that copy, or from any part of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">it. (Additional permissions may be written to require their own</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">removal in certain cases when you modify the work.) You may place</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">additional permissions on material, added by you to a covered work,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">for which you have or can give appropriate copyright permission.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Notwithstanding any other provision of this License, for material you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">add to a covered work, you may (if authorized by the copyright holders of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">that material) supplement the terms of this License with terms:</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> a) Disclaiming warranty or limiting liability differently from the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> terms of sections 15 and 16 of this License; or</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> b) Requiring preservation of specified reasonable legal notices or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> author attributions in that material or in the Appropriate Legal</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Notices displayed by works containing it; or</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> c) Prohibiting misrepresentation of the origin of that material, or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> requiring that modified versions of such material be marked in</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> reasonable ways as different from the original version; or</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> d) Limiting the use for publicity purposes of names of licensors or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> authors of the material; or</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> e) Declining to grant rights under trademark law for use of some</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> trade names, trademarks, or service marks; or</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> f) Requiring indemnification of licensors and authors of that</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> material by anyone who conveys the material (or modified versions of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> it) with contractual assumptions of liability to the recipient, for</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> any liability that these contractual assumptions directly impose on</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> those licensors and authors.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> All other non-permissive additional terms are considered \"further</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">restrictions\" within the meaning of section 10. If the Program as you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">received it, or any part of it, contains a notice stating that it is</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">governed by this License along with a term that is a further</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">restriction, you may remove that term. If a license document contains</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">a further restriction but permits relicensing or conveying under this</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">License, you may add to a covered work material governed by the terms</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">of that license document, provided that the further restriction does</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">not survive such relicensing or conveying.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> If you add terms to a covered work in accord with this section, you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">must place, in the relevant source files, a statement of the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">additional terms that apply to those files, or a notice indicating</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">where to find the applicable terms.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Additional terms, permissive or non-permissive, may be stated in the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">form of a separately written license, or stated as exceptions;</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the above requirements apply either way.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 8. Termination.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> You may not propagate or modify a covered work except as expressly</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">provided under this License. Any attempt otherwise to propagate or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">modify it is void, and will automatically terminate your rights under</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">this License (including any patent licenses granted under the third</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">paragraph of section 11).</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> However, if you cease all violation of this License, then your</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">license from a particular copyright holder is reinstated (a)</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">provisionally, unless and until the copyright holder explicitly and</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">finally terminates your license, and (b) permanently, if the copyright</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">holder fails to notify you of the violation by some reasonable means</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">prior to 60 days after the cessation.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Moreover, your license from a particular copyright holder is</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">reinstated permanently if the copyright holder notifies you of the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">violation by some reasonable means, this is the first time you have</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">received notice of violation of this License (for any work) from that</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">copyright holder, and you cure the violation prior to 30 days after</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">your receipt of the notice.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Termination of your rights under this section does not terminate the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">licenses of parties who have received copies or rights from you under</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">this License. If your rights have been terminated and not permanently</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">reinstated, you do not qualify to receive new licenses for the same</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">material under section 10.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 9. Acceptance Not Required for Having Copies.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> You are not required to accept this License in order to receive or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">run a copy of the Program. Ancillary propagation of a covered work</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">occurring solely as a consequence of using peer-to-peer transmission</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">to receive a copy likewise does not require acceptance. However,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">nothing other than this License grants you permission to propagate or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">modify any covered work. These actions infringe copyright if you do</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">not accept this License. Therefore, by modifying or propagating a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">covered work, you indicate your acceptance of this License to do so.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 10. Automatic Licensing of Downstream Recipients.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Each time you convey a covered work, the recipient automatically</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">receives a license from the original licensors, to run, modify and</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">propagate that work, subject to this License. You are not responsible</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">for enforcing compliance by third parties with this License.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> An \"entity transaction\" is a transaction transferring control of an</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">organization, or substantially all assets of one, or subdividing an</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">organization, or merging organizations. If propagation of a covered</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">work results from an entity transaction, each party to that</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">transaction who receives a copy of the work also receives whatever</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">licenses to the work the party\'s predecessor in interest had or could</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">give under the previous paragraph, plus a right to possession of the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Corresponding Source of the work from the predecessor in interest, if</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the predecessor has it or can get it with reasonable efforts.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> You may not impose any further restrictions on the exercise of the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">rights granted or affirmed under this License. For example, you may</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">not impose a license fee, royalty, or other charge for exercise of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">rights granted under this License, and you may not initiate litigation</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">(including a cross-claim or counterclaim in a lawsuit) alleging that</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">any patent claim is infringed by making, using, selling, offering for</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">sale, or importing the Program or any portion of it.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 11. Patents.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> A \"contributor\" is a copyright holder who authorizes use under this</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">License of the Program or a work on which the Program is based. The</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">work thus licensed is called the contributor\'s \"contributor version\".</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> A contributor\'s \"essential patent claims\" are all patent claims</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">owned or controlled by the contributor, whether already acquired or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">hereafter acquired, that would be infringed by some manner, permitted</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">by this License, of making, using, or selling its contributor version,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">but do not include claims that would be infringed only as a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">consequence of further modification of the contributor version. For</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">purposes of this definition, \"control\" includes the right to grant</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">patent sublicenses in a manner consistent with the requirements of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">this License.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Each contributor grants you a non-exclusive, worldwide, royalty-free</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">patent license under the contributor\'s essential patent claims, to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">make, use, sell, offer for sale, import and otherwise run, modify and</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">propagate the contents of its contributor version.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> In the following three paragraphs, a \"patent license\" is any express</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">agreement or commitment, however denominated, not to enforce a patent</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">(such as an express permission to practice a patent or covenant not to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">sue for patent infringement). To \"grant\" such a patent license to a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">party means to make such an agreement or commitment not to enforce a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">patent against the party.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> If you convey a covered work, knowingly relying on a patent license,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">and the Corresponding Source of the work is not available for anyone</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">to copy, free of charge and under the terms of this License, through a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">publicly available network server or other readily accessible means,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">then you must either (1) cause the Corresponding Source to be so</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">available, or (2) arrange to deprive yourself of the benefit of the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">patent license for this particular work, or (3) arrange, in a manner</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">consistent with the requirements of this License, to extend the patent</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">license to downstream recipients. \"Knowingly relying\" means you have</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">actual knowledge that, but for the patent license, your conveying the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">covered work in a country, or your recipient\'s use of the covered work</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">in a country, would infringe one or more identifiable patents in that</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">country that you have reason to believe are valid.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> If, pursuant to or in connection with a single transaction or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">arrangement, you convey, or propagate by procuring conveyance of, a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">covered work, and grant a patent license to some of the parties</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">receiving the covered work authorizing them to use, propagate, modify</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">or convey a specific copy of the covered work, then the patent license</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">you grant is automatically extended to all recipients of the covered</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">work and works based on it.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> A patent license is \"discriminatory\" if it does not include within</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the scope of its coverage, prohibits the exercise of, or is</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">conditioned on the non-exercise of one or more of the rights that are</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">specifically granted under this License. You may not convey a covered</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">work if you are a party to an arrangement with a third party that is</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">in the business of distributing software, under which you make payment</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">to the third party based on the extent of your activity of conveying</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the work, and under which the third party grants, to any of the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">parties who would receive the covered work from you, a discriminatory</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">patent license (a) in connection with copies of the covered work</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">conveyed by you (or copies made from those copies), or (b) primarily</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">for and in connection with specific products or compilations that</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">contain the covered work, unless you entered into that arrangement,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">or that patent license was granted, prior to 28 March 2007.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Nothing in this License shall be construed as excluding or limiting</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">any implied license or other defenses to infringement that may</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">otherwise be available to you under applicable patent law.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 12. No Surrender of Others\' Freedom.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> If conditions are imposed on you (whether by court order, agreement or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">otherwise) that contradict the conditions of this License, they do not</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">excuse you from the conditions of this License. If you cannot convey a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">covered work so as to satisfy simultaneously your obligations under this</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">License and any other pertinent obligations, then as a consequence you may</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">not convey it at all. For example, if you agree to terms that obligate you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">to collect a royalty for further conveying from those to whom you convey</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the Program, the only way you could satisfy both those terms and this</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">License would be to refrain entirely from conveying the Program.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 13. Use with the GNU Affero General Public License.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Notwithstanding any other provision of this License, you have</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">permission to link or combine any covered work with a work licensed</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">under version 3 of the GNU Affero General Public License into a single</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">combined work, and to convey the resulting work. The terms of this</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">License will continue to apply to the part which is the covered work,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">but the special requirements of the GNU Affero General Public License,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">section 13, concerning interaction through a network will apply to the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">combination as such.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 14. Revised Versions of this License.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The Free Software Foundation may publish revised and/or new versions of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the GNU General Public License from time to time. Such new versions will</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">be similar in spirit to the present version, but may differ in detail to</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">address new problems or concerns.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Each version is given a distinguishing version number. If the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Program specifies that a certain numbered version of the GNU General</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Public License \"or any later version\" applies to it, you have the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">option of following the terms and conditions either of that numbered</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">version or of any later version published by the Free Software</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Foundation. If the Program does not specify a version number of the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">GNU General Public License, you may choose any version ever published</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">by the Free Software Foundation.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> If the Program specifies that a proxy can decide which future</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">versions of the GNU General Public License can be used, that proxy\'s</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">public statement of acceptance of a version permanently authorizes you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">to choose that version for the Program.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Later license versions may give you additional or different</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">permissions. However, no additional obligations are imposed on any</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">author or copyright holder as a result of your choosing to follow a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">later version.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 15. Disclaimer of Warranty.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 16. Limitation of Liability.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">SUCH DAMAGES.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> 17. Interpretation of Sections 15 and 16.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> If the disclaimer of warranty and limitation of liability provided</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">above cannot be given local legal effect according to their terms,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">reviewing courts shall apply local law that most closely approximates</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">an absolute waiver of all civil liability in connection with the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Program, unless a warranty or assumption of liability accompanies a</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">copy of the Program in return for a fee.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> END OF TERMS AND CONDITIONS</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> How to Apply These Terms to Your New Programs</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> If you develop a new program, and you want it to be of the greatest</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">possible use to the public, the best way to achieve this is to make it</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">free software which everyone can redistribute and change under these terms.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> To do so, attach the following notices to the program. It is safest</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">to attach them to the start of each source file to most effectively</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">state the exclusion of warranty; and each file should have at least</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the \"copyright\" line and a pointer to where the full notice is found.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> &lt;one line to give the program\'s name and a brief idea of what it does.&gt;</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> Copyright (C) &lt;year&gt; &lt;name of author&gt;</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> This program is free software: you can redistribute it and/or modify</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> it under the terms of the GNU General Public License as published by</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> the Free Software Foundation, either version 3 of the License, or</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> (at your option) any later version.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> This program is distributed in the hope that it will be useful,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> but WITHOUT ANY WARRANTY; without even the implied warranty of</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> GNU General Public License for more details.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> You should have received a copy of the GNU General Public License</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Also add information on how to contact you by electronic and paper mail.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> If the program does terminal interaction, make it output a short</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">notice like this when it starts in an interactive mode:</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> &lt;program&gt; Copyright (C) &lt;year&gt; &lt;name of author&gt;</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> This program comes with ABSOLUTELY NO WARRANTY; for details type `show w\'.</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> This is free software, and you are welcome to redistribute it</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> under certain conditions; type `show c\' for details.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">The hypothetical commands `show w\' and `show c\' should show the appropriate</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">parts of the General Public License. Of course, your program\'s commands</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">might be different; for a GUI interface, you would use an \"about box\".</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> You should also get your employer (if you work as a programmer) or school,</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">if any, to sign a \"copyright disclaimer\" for the program, if necessary.</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">For more information on this, and how to apply and follow the GNU GPL, see</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">&lt;http://www.gnu.org/licenses/&gt;.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"> The GNU General Public License does not permit incorporating your program</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">into proprietary programs. If your program is a subroutine library, you</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">may consider it more useful to permit linking proprietary applications with</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">the library. If this is what you want to do, use the GNU Lesser General</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Public License instead of this License. But first, please read</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">&lt;http://www.gnu.org/philosophy/why-not-lgpl.html&gt;.</p>\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
self.abuttabs.setTabText(self.abuttabs.indexOf(self.licensetab), QtGui.QApplication.translate("Dialog", "License", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("Dialog", "Thanks to Wii.py team: Xuzz, SquidMan, megazig, TheLemonMan, |Omega, and Matt_P. Qwad is only a frontend for their unbelievably awesome framework.", None, QtGui.QApplication.UnicodeUTF8))
self.abuttabs.setTabText(self.abuttabs.indexOf(self.thankstab), QtGui.QApplication.translate("Dialog", "Thanks", None, QtGui.QApplication.UnicodeUTF8))
import Qwad_rc
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())

279
GUI/Ui_VenPri.py Normal file
View File

@ -0,0 +1,279 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '/home/ssorgatem/Documents/python/qwad/GUI/VenPri.ui'
#
# Created: Mon Jul 27 19:07:42 2009
# by: PyQt4 UI code generator 4.4.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
class Ui_Qwad(object):
def setupUi(self, Qwad):
Qwad.setObjectName("Qwad")
Qwad.resize(481, 296)
Qwad.setMinimumSize(QtCore.QSize(481, 296))
Qwad.setMaximumSize(QtCore.QSize(481, 296))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/icons/wad.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
Qwad.setWindowIcon(icon)
self.centralWidget = QtGui.QWidget(Qwad)
self.centralWidget.setObjectName("centralWidget")
self.tabWidget = QtGui.QTabWidget(self.centralWidget)
self.tabWidget.setGeometry(QtCore.QRect(0, 0, 481, 251))
self.tabWidget.setAcceptDrops(False)
self.tabWidget.setObjectName("tabWidget")
self.unpacktab = QtGui.QWidget()
self.unpacktab.setObjectName("unpacktab")
self.MuestraRutaWad = QtGui.QLineEdit(self.unpacktab)
self.MuestraRutaWad.setGeometry(QtCore.QRect(160, 40, 241, 26))
self.MuestraRutaWad.setObjectName("MuestraRutaWad")
self.BotonRutaWad = QtGui.QToolButton(self.unpacktab)
self.BotonRutaWad.setGeometry(QtCore.QRect(70, 40, 91, 25))
self.BotonRutaWad.setObjectName("BotonRutaWad")
self.MuestraRutaExtraer = QtGui.QLineEdit(self.unpacktab)
self.MuestraRutaExtraer.setGeometry(QtCore.QRect(160, 110, 241, 26))
self.MuestraRutaExtraer.setObjectName("MuestraRutaExtraer")
self.BotonRutaExtraer = QtGui.QToolButton(self.unpacktab)
self.BotonRutaExtraer.setGeometry(QtCore.QRect(70, 110, 91, 25))
self.BotonRutaExtraer.setAutoRaise(False)
self.BotonRutaExtraer.setArrowType(QtCore.Qt.NoArrow)
self.BotonRutaExtraer.setObjectName("BotonRutaExtraer")
self.Desempaqueta = QtGui.QPushButton(self.unpacktab)
self.Desempaqueta.setGeometry(QtCore.QRect(170, 180, 121, 25))
self.Desempaqueta.setObjectName("Desempaqueta")
self.tabWidget.addTab(self.unpacktab, "")
self.TMDviewer = QtGui.QWidget()
self.TMDviewer.setObjectName("TMDviewer")
self.TMDfilepath = QtGui.QLineEdit(self.TMDviewer)
self.TMDfilepath.setGeometry(QtCore.QRect(150, 10, 241, 26))
self.TMDfilepath.setObjectName("TMDfilepath")
self.TMDfilebutton = QtGui.QToolButton(self.TMDviewer)
self.TMDfilebutton.setGeometry(QtCore.QRect(60, 10, 91, 25))
self.TMDfilebutton.setObjectName("TMDfilebutton")
self.widget = QtGui.QWidget(self.TMDviewer)
self.widget.setGeometry(QtCore.QRect(10, 50, 451, 147))
self.widget.setObjectName("widget")
self.gridLayout = QtGui.QGridLayout(self.widget)
self.gridLayout.setObjectName("gridLayout")
self.label = QtGui.QLabel(self.widget)
self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.TitleID = QtGui.QLineEdit(self.widget)
self.TitleID.setReadOnly(True)
self.TitleID.setObjectName("TitleID")
self.gridLayout.addWidget(self.TitleID, 0, 1, 1, 1)
self.label_9 = QtGui.QLabel(self.widget)
self.label_9.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_9.setObjectName("label_9")
self.gridLayout.addWidget(self.label_9, 0, 2, 1, 2)
self.idASCII = QtGui.QLineEdit(self.widget)
self.idASCII.setReadOnly(True)
self.idASCII.setObjectName("idASCII")
self.gridLayout.addWidget(self.idASCII, 0, 4, 1, 1)
self.label_3 = QtGui.QLabel(self.widget)
self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
self.Version = QtGui.QLineEdit(self.widget)
self.Version.setReadOnly(True)
self.Version.setObjectName("Version")
self.gridLayout.addWidget(self.Version, 1, 1, 1, 1)
self.label_5 = QtGui.QLabel(self.widget)
self.label_5.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_5.setObjectName("label_5")
self.gridLayout.addWidget(self.label_5, 1, 3, 1, 1)
self.TitleType = QtGui.QLineEdit(self.widget)
self.TitleType.setReadOnly(True)
self.TitleType.setObjectName("TitleType")
self.gridLayout.addWidget(self.TitleType, 1, 4, 1, 1)
self.label_2 = QtGui.QLabel(self.widget)
self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.label_6 = QtGui.QLabel(self.widget)
self.label_6.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_6.setObjectName("label_6")
self.gridLayout.addWidget(self.label_6, 2, 3, 1, 1)
self.GroupID = QtGui.QLineEdit(self.widget)
self.GroupID.setReadOnly(True)
self.GroupID.setObjectName("GroupID")
self.gridLayout.addWidget(self.GroupID, 2, 4, 1, 1)
self.label_4 = QtGui.QLabel(self.widget)
self.label_4.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_4.setObjectName("label_4")
self.gridLayout.addWidget(self.label_4, 3, 0, 1, 1)
self.BootIndex = QtGui.QLineEdit(self.widget)
self.BootIndex.setReadOnly(True)
self.BootIndex.setObjectName("BootIndex")
self.gridLayout.addWidget(self.BootIndex, 3, 1, 1, 1)
self.label_7 = QtGui.QLabel(self.widget)
self.label_7.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_7.setObjectName("label_7")
self.gridLayout.addWidget(self.label_7, 3, 3, 1, 1)
self.AccessRights = QtGui.QLineEdit(self.widget)
self.AccessRights.setReadOnly(True)
self.AccessRights.setObjectName("AccessRights")
self.gridLayout.addWidget(self.AccessRights, 3, 4, 1, 1)
self.label_8 = QtGui.QLabel(self.widget)
self.label_8.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_8.setObjectName("label_8")
self.gridLayout.addWidget(self.label_8, 4, 0, 1, 1)
self.Contents = QtGui.QLineEdit(self.widget)
self.Contents.setReadOnly(True)
self.Contents.setObjectName("Contents")
self.gridLayout.addWidget(self.Contents, 4, 1, 1, 1)
self.IOSversion = QtGui.QComboBox(self.widget)
self.IOSversion.setObjectName("IOSversion")
self.gridLayout.addWidget(self.IOSversion, 2, 1, 1, 1)
self.tabWidget.addTab(self.TMDviewer, "")
self.packtab = QtGui.QWidget()
self.packtab.setObjectName("packtab")
self.MuestraRutaEmpaquetado = QtGui.QLineEdit(self.packtab)
self.MuestraRutaEmpaquetado.setGeometry(QtCore.QRect(160, 110, 241, 26))
self.MuestraRutaEmpaquetado.setObjectName("MuestraRutaEmpaquetado")
self.MuestraRutaDesempaquetado = QtGui.QLineEdit(self.packtab)
self.MuestraRutaDesempaquetado.setGeometry(QtCore.QRect(160, 40, 241, 26))
self.MuestraRutaDesempaquetado.setObjectName("MuestraRutaDesempaquetado")
self.BotonRutaEmpaquetado = QtGui.QToolButton(self.packtab)
self.BotonRutaEmpaquetado.setGeometry(QtCore.QRect(70, 110, 91, 25))
self.BotonRutaEmpaquetado.setAutoRaise(False)
self.BotonRutaEmpaquetado.setArrowType(QtCore.Qt.NoArrow)
self.BotonRutaEmpaquetado.setObjectName("BotonRutaEmpaquetado")
self.BotonRutaDesempaquetado = QtGui.QToolButton(self.packtab)
self.BotonRutaDesempaquetado.setGeometry(QtCore.QRect(70, 40, 91, 25))
self.BotonRutaDesempaquetado.setObjectName("BotonRutaDesempaquetado")
self.Empaqueta = QtGui.QPushButton(self.packtab)
self.Empaqueta.setGeometry(QtCore.QRect(170, 180, 121, 25))
self.Empaqueta.setObjectName("Empaqueta")
self.tabWidget.addTab(self.packtab, "")
self.NUStab = QtGui.QWidget()
self.NUStab.setObjectName("NUStab")
self.NusOutputPath = QtGui.QLineEdit(self.NUStab)
self.NusOutputPath.setGeometry(QtCore.QRect(140, 150, 241, 26))
self.NusOutputPath.setObjectName("NusOutputPath")
self.Download_from_NUS = QtGui.QPushButton(self.NUStab)
self.Download_from_NUS.setGeometry(QtCore.QRect(170, 180, 121, 25))
self.Download_from_NUS.setObjectName("Download_from_NUS")
self.NusOutputButton = QtGui.QToolButton(self.NUStab)
self.NusOutputButton.setGeometry(QtCore.QRect(40, 150, 91, 25))
self.NusOutputButton.setAutoRaise(False)
self.NusOutputButton.setArrowType(QtCore.Qt.NoArrow)
self.NusOutputButton.setObjectName("NusOutputButton")
self.enteredTitleID = QtGui.QLineEdit(self.NUStab)
self.enteredTitleID.setGeometry(QtCore.QRect(125, 45, 161, 31))
self.enteredTitleID.setObjectName("enteredTitleID")
self.TitleIDlabel = QtGui.QLabel(self.NUStab)
self.TitleIDlabel.setGeometry(QtCore.QRect(15, 51, 101, 20))
self.TitleIDlabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTop|QtCore.Qt.AlignTrailing)
self.TitleIDlabel.setObjectName("TitleIDlabel")
self.Title = QtGui.QLabel(self.NUStab)
self.Title.setGeometry(QtCore.QRect(0, 10, 121, 21))
self.Title.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.Title.setObjectName("Title")
self.comboBox = QtGui.QComboBox(self.NUStab)
self.comboBox.setGeometry(QtCore.QRect(125, 10, 291, 25))
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem(QtCore.QString())
self.decryptCheck = QtGui.QCheckBox(self.NUStab)
self.decryptCheck.setEnabled(False)
self.decryptCheck.setGeometry(QtCore.QRect(130, 80, 171, 23))
self.decryptCheck.setChecked(False)
self.decryptCheck.setObjectName("decryptCheck")
self.pack_in_WAD_checkbox = QtGui.QCheckBox(self.NUStab)
self.pack_in_WAD_checkbox.setGeometry(QtCore.QRect(130, 110, 181, 23))
self.pack_in_WAD_checkbox.setChecked(True)
self.pack_in_WAD_checkbox.setObjectName("pack_in_WAD_checkbox")
self.VersionlineEdit = QtGui.QLineEdit(self.NUStab)
self.VersionlineEdit.setGeometry(QtCore.QRect(340, 45, 71, 31))
self.VersionlineEdit.setObjectName("VersionlineEdit")
self.versionlabel = QtGui.QLabel(self.NUStab)
self.versionlabel.setGeometry(QtCore.QRect(290, 50, 51, 20))
self.versionlabel.setObjectName("versionlabel")
self.tabWidget.addTab(self.NUStab, "")
Qwad.setCentralWidget(self.centralWidget)
self.menuBar = QtGui.QMenuBar(Qwad)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 481, 22))
self.menuBar.setObjectName("menuBar")
self.menuAyuda = QtGui.QMenu(self.menuBar)
self.menuAyuda.setObjectName("menuAyuda")
Qwad.setMenuBar(self.menuBar)
self.statusBar = QtGui.QStatusBar(Qwad)
self.statusBar.setObjectName("statusBar")
Qwad.setStatusBar(self.statusBar)
self.actionAcerca_de_Qwad = QtGui.QAction(Qwad)
self.actionAcerca_de_Qwad.setIcon(icon)
self.actionAcerca_de_Qwad.setObjectName("actionAcerca_de_Qwad")
self.actionAbout_Qt = QtGui.QAction(Qwad)
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/icons/qt4.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionAbout_Qt.setIcon(icon1)
self.actionAbout_Qt.setObjectName("actionAbout_Qt")
self.actionAbout_Wii_Signer = QtGui.QAction(Qwad)
self.actionAbout_Wii_Signer.setObjectName("actionAbout_Wii_Signer")
self.menuAyuda.addAction(self.actionAcerca_de_Qwad)
self.menuAyuda.addAction(self.actionAbout_Qt)
self.menuBar.addAction(self.menuAyuda.menuAction())
self.retranslateUi(Qwad)
self.tabWidget.setCurrentIndex(1)
QtCore.QMetaObject.connectSlotsByName(Qwad)
def retranslateUi(self, Qwad):
Qwad.setWindowTitle(QtGui.QApplication.translate("Qwad", "Qwad - a WAD management tool", None, QtGui.QApplication.UnicodeUTF8))
self.BotonRutaWad.setToolTip(QtGui.QApplication.translate("Qwad", "Ruta hacia el archivo WAD que quieres desempaquetar", None, QtGui.QApplication.UnicodeUTF8))
self.BotonRutaWad.setText(QtGui.QApplication.translate("Qwad", "WAD file", None, QtGui.QApplication.UnicodeUTF8))
self.BotonRutaExtraer.setToolTip(QtGui.QApplication.translate("Qwad", "Carpeta donde se almacenaran los contenidos del archivo WAD", None, QtGui.QApplication.UnicodeUTF8))
self.BotonRutaExtraer.setText(QtGui.QApplication.translate("Qwad", "Output", None, QtGui.QApplication.UnicodeUTF8))
self.Desempaqueta.setText(QtGui.QApplication.translate("Qwad", "Unpack", None, QtGui.QApplication.UnicodeUTF8))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.unpacktab), QtGui.QApplication.translate("Qwad", "Unpack WAD", None, QtGui.QApplication.UnicodeUTF8))
self.TMDfilebutton.setToolTip(QtGui.QApplication.translate("Qwad", "Ruta hacia el archivo WAD que quieres desempaquetar", None, QtGui.QApplication.UnicodeUTF8))
self.TMDfilebutton.setText(QtGui.QApplication.translate("Qwad", "TMD file", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("Qwad", "Title ID", None, QtGui.QApplication.UnicodeUTF8))
self.TitleID.setText(QtGui.QApplication.translate("Qwad", "0000000000000000", None, QtGui.QApplication.UnicodeUTF8))
self.label_9.setText(QtGui.QApplication.translate("Qwad", "ID (ascii)", None, QtGui.QApplication.UnicodeUTF8))
self.label_3.setText(QtGui.QApplication.translate("Qwad", "Version", None, QtGui.QApplication.UnicodeUTF8))
self.Version.setText(QtGui.QApplication.translate("Qwad", "0", None, QtGui.QApplication.UnicodeUTF8))
self.label_5.setText(QtGui.QApplication.translate("Qwad", "Title type", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("Qwad", "IOS needed", None, QtGui.QApplication.UnicodeUTF8))
self.label_6.setText(QtGui.QApplication.translate("Qwad", "Group ID", None, QtGui.QApplication.UnicodeUTF8))
self.label_4.setText(QtGui.QApplication.translate("Qwad", "Boot index", None, QtGui.QApplication.UnicodeUTF8))
self.label_7.setText(QtGui.QApplication.translate("Qwad", "Access rights", None, QtGui.QApplication.UnicodeUTF8))
self.label_8.setText(QtGui.QApplication.translate("Qwad", "Contents", None, QtGui.QApplication.UnicodeUTF8))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.TMDviewer), QtGui.QApplication.translate("Qwad", "TMD viewer", None, QtGui.QApplication.UnicodeUTF8))
self.BotonRutaEmpaquetado.setToolTip(QtGui.QApplication.translate("Qwad", "Carpeta y nombre del nuevo WAD", None, QtGui.QApplication.UnicodeUTF8))
self.BotonRutaEmpaquetado.setText(QtGui.QApplication.translate("Qwad", "Output", None, QtGui.QApplication.UnicodeUTF8))
self.BotonRutaDesempaquetado.setToolTip(QtGui.QApplication.translate("Qwad", "Ruta hacia la carpeta que empaquetar en WAD", None, QtGui.QApplication.UnicodeUTF8))
self.BotonRutaDesempaquetado.setText(QtGui.QApplication.translate("Qwad", "Folder", None, QtGui.QApplication.UnicodeUTF8))
self.Empaqueta.setText(QtGui.QApplication.translate("Qwad", "Pack", None, QtGui.QApplication.UnicodeUTF8))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.packtab), QtGui.QApplication.translate("Qwad", "Pack WAD", None, QtGui.QApplication.UnicodeUTF8))
self.Download_from_NUS.setText(QtGui.QApplication.translate("Qwad", "Download", None, QtGui.QApplication.UnicodeUTF8))
self.NusOutputButton.setToolTip(QtGui.QApplication.translate("Qwad", "Carpeta y nombre del nuevo WAD", None, QtGui.QApplication.UnicodeUTF8))
self.NusOutputButton.setText(QtGui.QApplication.translate("Qwad", "Output", None, QtGui.QApplication.UnicodeUTF8))
self.enteredTitleID.setText(QtGui.QApplication.translate("Qwad", "000000000000000000", None, QtGui.QApplication.UnicodeUTF8))
self.TitleIDlabel.setText(QtGui.QApplication.translate("Qwad", "Title ID", None, QtGui.QApplication.UnicodeUTF8))
self.Title.setText(QtGui.QApplication.translate("Qwad", "Choose title:", None, QtGui.QApplication.UnicodeUTF8))
self.comboBox.setItemText(0, QtGui.QApplication.translate("Qwad", "Custom title ID", None, QtGui.QApplication.UnicodeUTF8))
self.decryptCheck.setText(QtGui.QApplication.translate("Qwad", "Decrypt", None, QtGui.QApplication.UnicodeUTF8))
self.pack_in_WAD_checkbox.setText(QtGui.QApplication.translate("Qwad", "Pack into WAD", None, QtGui.QApplication.UnicodeUTF8))
self.VersionlineEdit.setText(QtGui.QApplication.translate("Qwad", "unset", None, QtGui.QApplication.UnicodeUTF8))
self.versionlabel.setText(QtGui.QApplication.translate("Qwad", "Version:", None, QtGui.QApplication.UnicodeUTF8))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.NUStab), QtGui.QApplication.translate("Qwad", "Download from NUS", None, QtGui.QApplication.UnicodeUTF8))
self.menuAyuda.setTitle(QtGui.QApplication.translate("Qwad", "Help", None, QtGui.QApplication.UnicodeUTF8))
self.actionAcerca_de_Qwad.setText(QtGui.QApplication.translate("Qwad", "About Qwad", None, QtGui.QApplication.UnicodeUTF8))
self.actionAbout_Qt.setText(QtGui.QApplication.translate("Qwad", "About Qt", None, QtGui.QApplication.UnicodeUTF8))
self.actionAbout_Wii_Signer.setText(QtGui.QApplication.translate("Qwad", "About Wii Signer", None, QtGui.QApplication.UnicodeUTF8))
import Qwad_rc
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Qwad = QtGui.QMainWindow()
ui = Ui_Qwad()
ui.setupUi(Qwad)
Qwad.show()
sys.exit(app.exec_())

337
GUI/VenPri.py Normal file
View File

@ -0,0 +1,337 @@
# -*- coding: utf-8 -*-
"""
Module implementing Qwad's main window
"""
from PyQt4.QtGui import QMainWindow,QFileDialog,QMessageBox, QLabel
from PyQt4.QtCore import pyqtSignature,QString,QT_TR_NOOP,SIGNAL,QObject
from WiiPy.archive import WAD
from WiiPy.title import NUS, TMD
from Ui_VenPri import Ui_Qwad
from shutil import rmtree
from threading import Thread
import TitleIDs
import tempfile, os, time
CWD = os.getcwd()
class MWQwad(QMainWindow, Ui_Qwad):
"""
Class documentation goes here.
"""
def __init__(self, parent = None):
"""
Constructor
"""
QMainWindow.__init__(self, parent)
self.setupUi(self)
self.defaultversion = self.trUtf8("""(Latest)""")
self.VersionlineEdit.setText(self.defaultversion)
for key in sorted(TitleIDs.TitleDict):
self.comboBox.addItem(key)
for ios in sorted(TitleIDs.IOSdict):
self.IOSversion.addItem(ios)
self.getReady()
def Status(self,status):
print status
self.setEnabled(False)
self.statusBar.showMessage(status)
def getReady(self):
self.setEnabled(True)
self.statusBar.showMessage(self.trUtf8("Ready"))
os.chdir(CWD)
print "Done."
def ErrorDiag(self, error = QT_TR_NOOP("Unknown error")):
print error
QMessageBox.critical(None,
self.trUtf8("Error"),
self.trUtf8("""An error has ocurred:""") +" " + str(error),
QMessageBox.StandardButtons(\
QMessageBox.Ok),
QMessageBox.Ok)
def loadTMD(self,tmdpath):#TODO: TMD viewer
"""
Displays _TMD information in the UI
"""
tmd = TMD().loadFile(tmdpath)
self.TitleID.setText("%016x" % tmd.tmd.titleid)
# print tmd.tmd.version
#self.IOSversion.setText("%016x" % tmd.tmd.iosversion)
self.TitleType.setText(str(tmd.tmd.title_type))
self.GroupID.setText(str(tmd.tmd.group_id))
# print tmd.tmd.reserved
self.AccessRights.setText(str(tmd.tmd.access_rights))
self.Version.setText(str(tmd.tmd.title_version))
self.Contents.setText(str(tmd.tmd.numcontents))
self.BootIndex.setText(str(tmd.tmd.boot_index))
@pyqtSignature("")
def on_BotonRutaWad_clicked(self):
"""
Get path to WAD file
"""
WadPath = QFileDialog.getOpenFileName(\
None,
self.trUtf8("Select WAD file"),
QString(),
self.trUtf8("*.wad; *.WAD"),
None)
if WadPath != "" :
self.MuestraRutaWad.setText(WadPath)
@pyqtSignature("")
def on_BotonRutaExtraer_clicked(self):
"""
WAD contents output path
"""
OutputDir = QFileDialog.getExistingDirectory(\
None,
self.trUtf8("Select where to store WAD contents"),
QString(),
QFileDialog.Options(QFileDialog.ShowDirsOnly))
if OutputDir != "":
self.MuestraRutaExtraer.setText(OutputDir)
@pyqtSignature("")
def on_Desempaqueta_clicked(self):
"""
Unpack wad
"""
try:
self.unpack = Unpacking(str(self.MuestraRutaWad.text()), str(self.MuestraRutaExtraer.text()), self)
self.unpack.start()
except Exception, e:
self.ErrorDiag(e)
@pyqtSignature("")
def on_BotonRutaEmpaquetado_clicked(self):
"""
Select where to save the newly created WAD
"""
NewWadPath = QFileDialog.getSaveFileName(\
None,
self.trUtf8("Select where to save the newly created WAD"),
QString("output.wad"),
self.trUtf8("*.wad; *.WAD"),
None)
if NewWadPath != "":
self.MuestraRutaEmpaquetado.setText(NewWadPath)
@pyqtSignature("")
def on_BotonRutaDesempaquetado_clicked(self):
"""
Get path off folder to pack.
"""
Dir2Wad = QFileDialog.getExistingDirectory(\
None,
self.trUtf8("Select folder to pack into WAD"),
QString(),
QFileDialog.Options(QFileDialog.ShowDirsOnly))
if Dir2Wad != "":
self.MuestraRutaDesempaquetado.setText(Dir2Wad)
@pyqtSignature("")
def on_Empaqueta_clicked(self):
"""
Create WAD
"""
self.setEnabled(False)
try:
self.packing = Packing(str(self.MuestraRutaDesempaquetado.text()),str(self.MuestraRutaEmpaquetado.text()), self)
self.packing.start()
except Exception, e:
self.ErrorDiag(e)
self.setEnabled(True)
@pyqtSignature("")
def on_actionAcerca_de_Qwad_triggered(self):
"""
About Qwad
"""
from AboutQwad import AboutQwad
Pop = AboutQwad()
Pop.exec_()
@pyqtSignature("")
def on_actionAbout_Qt_triggered(self):
"""
About Qt
"""
QMessageBox.aboutQt(None,
self.trUtf8("About Qt"))
@pyqtSignature("")
def on_Download_from_NUS_clicked(self):
"""
Start doing the actual work... well, in fact, the actual work is done by Wii.py
"""
try:
version = self.VersionlineEdit.text()
if version == self.defaultversion:
print "downloading latest version"
version = None
else:
version = str(version)
print "downloading version " + version
outputdir = str(self.NusOutputPath.text())
self.nusdow = nusDownloading(int(str(self.enteredTitleID.text()).lower(),16), version, outputdir, self.decryptCheck.isChecked(), self)
self.nusdow.start()
except Exception, e:
self.ErrorDiag(e)
@pyqtSignature("")
def on_NusOutputButton_clicked(self):
"""
Selects the output path
"""
if self.pack_in_WAD_checkbox.isChecked():
outputdir = QFileDialog.getSaveFileName(\
None,
self.trUtf8("Select where to save the downloaded WAD"),
QString(),
self.trUtf8("*.wad; *.WAD"),
None)
else:
outputdir = QFileDialog.getExistingDirectory(\
None,
self.trUtf8("Select the directory where store the downloaded files"),
QString(),
QFileDialog.Options(QFileDialog.ShowDirsOnly))
if outputdir != "":
self.NusOutputPath.setText(outputdir)
@pyqtSignature("QString")
def on_comboBox_currentIndexChanged(self, selection):
"""
Show the title ID of the selected title
"""
if self.comboBox.findText(selection) != 0:
self.enteredTitleID.enabled = False
self.enteredTitleID.setText(TitleIDs.TitleDict[str(selection)])
@pyqtSignature("")
def on_enteredTitleID_returnPressed(self):
"""
Place combobox un custom titleid
"""
self.comboBox.setCurrentIndex(0)
@pyqtSignature("int")
def on_pack_in_WAD_checkbox_stateChanged(self, state):
"""
Clear output path, because we change output type
"""
self.NusOutputPath.clear()
if state == 2:
self.decryptCheck.setChecked(False)
self.decryptCheck.setEnabled(False)
elif state == 0:
self.decryptCheck.setChecked(True)
self.decryptCheck.setEnabled(True)
elif state == 1:
print "OMG, what are you doing?"
else:
print "This is the end of the world. For PyQt4, at least"
@pyqtSignature("")
def on_TMDfilepath_returnPressed(self):
"""
Trigger loadTMD
"""
self.loadTMD(str(self.TMDfilepath.text()))
@pyqtSignature("")
def on_TMDfilebutton_clicked(self):
"""
Trigger loadTMD
"""
tmdpath = QFileDialog.getOpenFileName(\
None,
self.trUtf8("Select a TMD file"),
QString(),
self.trUtf8("tmd; TMD"),
None,
QFileDialog.Options(QFileDialog.DontResolveSymlinks))
if tmdpath != "":
self.TMDfilepath.setText(tmdpath)
self.loadTMD(str(tmdpath))
#Here useful thread classes
class Unpacking(Thread):
def __init__(self, wadpath, dirpath, QMW):
Thread.__init__(self)
self.wadpath = wadpath
self.dirpath = dirpath
self.QMW = QMW
self.qobject = QObject()
self.qobject.connect(self.qobject, SIGNAL("working"),self.QMW.Status)
self.qobject.connect(self.qobject, SIGNAL("Exception"),self.QMW.ErrorDiag)
self.qobject.connect(self.qobject, SIGNAL("Done"),self.QMW.getReady)
def run(self):
self.qobject.emit(SIGNAL("working"),UNPACKING)
try:
WAD.loadFile(self.wadpath).dumpDir(self.dirpath)
except Exception, e:
print e
self.qobject.emit(SIGNAL("Exception"),e)
self.qobject.emit(SIGNAL("Done"))
class Packing(Unpacking):
def __init__(self, dirpath, wadpath, QMW, deletedir = False):
Unpacking.__init__(self, wadpath, dirpath, QMW)
self.deletedir = deletedir
def run(self):
self.qobject.emit(SIGNAL("working"),PACKING)
try:
print self.dirpath
print self.wadpath
WAD.loadDir(self.dirpath).dumpFile(self.wadpath)
if self.deletedir:
print "Cleaning temporary files"
self.qobject.emit(SIGNAL("working"),CLEANING)
rmtree(self.dirpath)
except Exception, e:
if self.deletedir:
print "Cleaning temporary files"
self.qobject.emit(SIGNAL("working"),CLEANING)
rmtree(self.dirpath)
print e
self.qobject.emit(SIGNAL("Exception"),e)
self.qobject.emit(SIGNAL("Done"))
class nusDownloading(Unpacking):
def __init__(self, titleid, version, outputdir, decrypt, QMW):
Unpacking.__init__(self, None, outputdir, QMW)
if version != None:
self.version = int(version)
else:
self.version = None
self.decrypt = decrypt
self.titleid = titleid
def run(self):
self.qobject.emit(SIGNAL("working"),DOWNLOADING)
try:
if self.QMW.pack_in_WAD_checkbox.isChecked():
self.dirpath = tempfile.gettempdir() + "/NUS_"+ str(time.time()).replace(".","") # A safe place for temporary files
NUS(self.titleid,self.version).download(self.dirpath, decrypt = self.decrypt)
self.packing = Packing(self.dirpath, str(self.QMW.NusOutputPath.text()), self.QMW, True)
self.packing.start()
else:
NUS(self.titleid,self.version).download(self.dirpath, decrypt = self.decrypt)
self.qobject.emit(SIGNAL("Done"))
except Exception, e:
print e
Errormsg = str(e) + ". " + QT_TR_NOOP(QString("Title %1 version %2 maybe isn't available for download on NUS.").arg(str(self.titleid)).arg(str(self.version)))
self.qobject.emit(SIGNAL("Exception"),Errormsg)
self.qobject.emit(SIGNAL("Done"))
#Statusbar messages
#FIXME: Why don't they get translated? It's frustrating
DOWNLOADING = QT_TR_NOOP("Downloading files from NUS... This may take a while, please, be patient.")
UNPACKING = QT_TR_NOOP("Unpacking WAD...")
PACKING = QT_TR_NOOP("Packing into WAD...")
CLEANING = QT_TR_NOOP("Cleaning temporary files...")

633
GUI/VenPri.ui Normal file
View File

@ -0,0 +1,633 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Qwad</class>
<widget class="QMainWindow" name="Qwad">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>481</width>
<height>296</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>481</width>
<height>296</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>481</width>
<height>296</height>
</size>
</property>
<property name="windowTitle">
<string>Qwad - a WAD management tool</string>
</property>
<property name="windowIcon">
<iconset resource="../Qwad.qrc">
<normaloff>:/icons/wad.png</normaloff>:/icons/wad.png</iconset>
</property>
<property name="locale">
<locale language="Spanish" country="Spain"/>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QTabWidget" name="tabWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>481</width>
<height>251</height>
</rect>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="unpacktab">
<attribute name="title">
<string>Unpack WAD</string>
</attribute>
<widget class="QLineEdit" name="MuestraRutaWad">
<property name="geometry">
<rect>
<x>160</x>
<y>40</y>
<width>241</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QToolButton" name="BotonRutaWad">
<property name="geometry">
<rect>
<x>70</x>
<y>40</y>
<width>91</width>
<height>25</height>
</rect>
</property>
<property name="toolTip">
<string>Ruta hacia el archivo WAD que quieres desempaquetar</string>
</property>
<property name="text">
<string>WAD file</string>
</property>
</widget>
<widget class="QLineEdit" name="MuestraRutaExtraer">
<property name="geometry">
<rect>
<x>160</x>
<y>110</y>
<width>241</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QToolButton" name="BotonRutaExtraer">
<property name="geometry">
<rect>
<x>70</x>
<y>110</y>
<width>91</width>
<height>25</height>
</rect>
</property>
<property name="toolTip">
<string>Carpeta donde se almacenaran los contenidos del archivo WAD</string>
</property>
<property name="text">
<string>Output</string>
</property>
<property name="autoRaise">
<bool>false</bool>
</property>
<property name="arrowType">
<enum>Qt::NoArrow</enum>
</property>
</widget>
<widget class="QPushButton" name="Desempaqueta">
<property name="geometry">
<rect>
<x>170</x>
<y>180</y>
<width>121</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Unpack</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="TMDviewer">
<attribute name="title">
<string>TMD viewer</string>
</attribute>
<widget class="QLineEdit" name="TMDfilepath">
<property name="geometry">
<rect>
<x>150</x>
<y>10</y>
<width>241</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QToolButton" name="TMDfilebutton">
<property name="geometry">
<rect>
<x>60</x>
<y>10</y>
<width>91</width>
<height>25</height>
</rect>
</property>
<property name="toolTip">
<string>Ruta hacia el archivo WAD que quieres desempaquetar</string>
</property>
<property name="text">
<string>TMD file</string>
</property>
</widget>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>451</width>
<height>147</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Title ID</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="TitleID">
<property name="text">
<string>0000000000000000</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2" colspan="2">
<widget class="QLabel" name="label_9">
<property name="text">
<string>ID (ascii)</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLineEdit" name="idASCII">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Version</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="Version">
<property name="text">
<string>0</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Title type</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLineEdit" name="TitleType">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>IOS needed</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Group ID</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QLineEdit" name="GroupID">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Boot index</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="BootIndex">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Access rights</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QLineEdit" name="AccessRights">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Contents</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="Contents">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="IOSversion"/>
</item>
</layout>
</widget>
</widget>
<widget class="QWidget" name="packtab">
<attribute name="title">
<string>Pack WAD</string>
</attribute>
<widget class="QLineEdit" name="MuestraRutaEmpaquetado">
<property name="geometry">
<rect>
<x>160</x>
<y>110</y>
<width>241</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="MuestraRutaDesempaquetado">
<property name="geometry">
<rect>
<x>160</x>
<y>40</y>
<width>241</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QToolButton" name="BotonRutaEmpaquetado">
<property name="geometry">
<rect>
<x>70</x>
<y>110</y>
<width>91</width>
<height>25</height>
</rect>
</property>
<property name="toolTip">
<string>Carpeta y nombre del nuevo WAD</string>
</property>
<property name="text">
<string>Output</string>
</property>
<property name="autoRaise">
<bool>false</bool>
</property>
<property name="arrowType">
<enum>Qt::NoArrow</enum>
</property>
</widget>
<widget class="QToolButton" name="BotonRutaDesempaquetado">
<property name="geometry">
<rect>
<x>70</x>
<y>40</y>
<width>91</width>
<height>25</height>
</rect>
</property>
<property name="toolTip">
<string>Ruta hacia la carpeta que empaquetar en WAD</string>
</property>
<property name="text">
<string>Folder</string>
</property>
</widget>
<widget class="QPushButton" name="Empaqueta">
<property name="geometry">
<rect>
<x>170</x>
<y>180</y>
<width>121</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Pack</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="NUStab">
<attribute name="title">
<string>Download from NUS</string>
</attribute>
<widget class="QLineEdit" name="NusOutputPath">
<property name="geometry">
<rect>
<x>140</x>
<y>150</y>
<width>241</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="Download_from_NUS">
<property name="geometry">
<rect>
<x>170</x>
<y>180</y>
<width>121</width>
<height>25</height>
</rect>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="text">
<string>Download</string>
</property>
</widget>
<widget class="QToolButton" name="NusOutputButton">
<property name="geometry">
<rect>
<x>40</x>
<y>150</y>
<width>91</width>
<height>25</height>
</rect>
</property>
<property name="toolTip">
<string>Carpeta y nombre del nuevo WAD</string>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="text">
<string>Output</string>
</property>
<property name="autoRaise">
<bool>false</bool>
</property>
<property name="arrowType">
<enum>Qt::NoArrow</enum>
</property>
</widget>
<widget class="QLineEdit" name="enteredTitleID">
<property name="geometry">
<rect>
<x>125</x>
<y>45</y>
<width>161</width>
<height>31</height>
</rect>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="text">
<string>000000000000000000</string>
</property>
</widget>
<widget class="QLabel" name="TitleIDlabel">
<property name="geometry">
<rect>
<x>15</x>
<y>51</y>
<width>101</width>
<height>20</height>
</rect>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="text">
<string>Title ID</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
</property>
</widget>
<widget class="QLabel" name="Title">
<property name="geometry">
<rect>
<x>0</x>
<y>10</y>
<width>121</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Choose title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>125</x>
<y>10</y>
<width>291</width>
<height>25</height>
</rect>
</property>
<item>
<property name="text">
<string>Custom title ID</string>
</property>
</item>
</widget>
<widget class="QCheckBox" name="decryptCheck">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>130</x>
<y>80</y>
<width>171</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Decrypt</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
<widget class="QCheckBox" name="pack_in_WAD_checkbox">
<property name="geometry">
<rect>
<x>130</x>
<y>110</y>
<width>181</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Pack into WAD</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<widget class="QLineEdit" name="VersionlineEdit">
<property name="geometry">
<rect>
<x>340</x>
<y>45</y>
<width>71</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>unset</string>
</property>
</widget>
<widget class="QLabel" name="versionlabel">
<property name="geometry">
<rect>
<x>290</x>
<y>50</y>
<width>51</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Version:</string>
</property>
</widget>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>481</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuAyuda">
<property name="title">
<string>Help</string>
</property>
<addaction name="actionAcerca_de_Qwad"/>
<addaction name="actionAbout_Qt"/>
</widget>
<addaction name="menuAyuda"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionAcerca_de_Qwad">
<property name="icon">
<iconset resource="../Qwad.qrc">
<normaloff>:/icons/wad.png</normaloff>:/icons/wad.png</iconset>
</property>
<property name="text">
<string>About Qwad</string>
</property>
</action>
<action name="actionAbout_Qt">
<property name="icon">
<iconset resource="../Qwad.qrc">
<normaloff>:/icons/qt4.png</normaloff>:/icons/qt4.png</iconset>
</property>
<property name="text">
<string>About Qt</string>
</property>
</action>
<action name="actionAbout_Wii_Signer">
<property name="text">
<string>About Wii Signer</string>
</property>
</action>
</widget>
<resources>
<include location="../Qwad.qrc"/>
</resources>
<connections/>
</ui>

0
GUI/__init__.py Normal file
View File

3
Qwad.pro Normal file
View File

@ -0,0 +1,3 @@
TRANSLATIONS = i18n/Qwad_es.ts \
i18n/Qwad_en.ts \
i18n/Qwad_ca.ts \

21
Qwad.pyw Normal file
View File

@ -0,0 +1,21 @@
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QTranslator, QString, QLocale
from GUI.VenPri import MWQwad
if __name__ == "__main__":
translator = QTranslator()
translator.load(QString("i18n/Qwad_%1").arg(QLocale.system().name()))
qttranslator = QTranslator()
qttranslator.load(QString("qt_%1").arg(QLocale.system().name()))
Vapp = QApplication(sys.argv)
Vapp.setOrganizationName("ssorgatem productions")
Vapp.setApplicationName("Qwad")
Vapp.installTranslator(translator)
Vapp.installTranslator(qttranslator)
VentanaP = MWQwad()
VentanaP.show()
sys.exit(Vapp.exec_())

7
Qwad.qrc Normal file
View File

@ -0,0 +1,7 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file>icons/wad.png</file>
<file>icons/qt4.png</file>
</qresource>
</RCC>

2154
Qwad_rc.py Normal file

File diff suppressed because it is too large Load Diff

90
TitleIDs.py Normal file
View File

@ -0,0 +1,90 @@
#-*- coding: utf-8 -*-
"""
module storing a titleid dictionary
"""
import binascii, re
from PyQt4.QtCore import QT_TR_NOOP
TitleDict = {
#"BOOT2":"0000000100000001",
"System Menu":"0000000100000002",
#"BC":"0000000100000100",
"MIOS":"0000000100000101",
"IOS4":"0000000100000004",
"IOS9":"0000000100000009",
"IOS10":"000000010000000a",
"IOS11":"000000010000000b",
"IOS12":"000000010000000c",
"IOS13":"000000010000000d",
"IOS14":"000000010000000e",
"IOS15":"000000010000000f",
"IOS16":"0000000100000010",
"IOS17":"0000000100000011",
"IOS20":"0000000100000014",
"IOS21":"0000000100000015",
"IOS22":"0000000100000016",
"IOS28":"000000010000001c",
"IOS30":"000000010000001e",
"IOS31":"000000010000001f",
"IOS33":"0000000100000021",
"IOS34":"0000000100000022",
"IOS35":"0000000100000023",
"IOS36":"0000000100000024",
"IOS37":"0000000100000025",
"IOS38":"0000000100000026",
"IOS50":"0000000100000032",
"IOS51":"0000000100000033",
"IOS53":"0000000100000035",
"IOS55":"0000000100000037",
"IOS60":"000000010000003c",
"IOS61":"000000010000003d",
"IOS254":"00000001000000fe",
#TODO: Add remaining IOSes
#QT_TR_NOOP("Wii Speak Channel"):"00010001484346xx",
#QT_TR_NOOP("Photo Channel 1.1 [USA]"):"0001000148415a45",
QT_TR_NOOP("Photo Channel 1.1 [PAL]"):"0001000148415a50",
#QT_TR_NOOP("Photo Channel 1.1 [JAP]"):"0001000148415a4a",
#QT_TR_NOOP("Metroid Prime 3 Preview"):"00010001484157xx",
QT_TR_NOOP("Nintendo Channel"):"00010001484154xx",
QT_TR_NOOP("Check Mii Out / Mii Contest Channel[USA]"):"0001000148415045",
QT_TR_NOOP("Check Mii Out / Mii Contest Channel[PAL]"):"0001000148415050",
QT_TR_NOOP("Check Mii Out / Mii Contest Channel[JAP]"):"000100014841504A",
QT_TR_NOOP("Everyone Votes Channel[USA]"):"0001000148414a45",
QT_TR_NOOP("Everyone Votes Channel[PAL]"):"0001000148414a50",
QT_TR_NOOP("Everyone Votes Channel[JAP]"):"0001000148414a4A",
#QT_TR_NOOP("Opera / Internet Channel"):"00010001484144xx",
QT_TR_NOOP("Photo Channel"):"0001000248414141",
QT_TR_NOOP("Shopping Channel"):"0001000248414241",
QT_TR_NOOP("Mii Channel"):"001000248414341",
QT_TR_NOOP("Photo Channel 1.1"):"001000248415941",
#QT_TR_NOOP("Wii Message Board"):"001000148414541",
#QT_TR_NOOP("Weather Channel-HAFx"):"00010002484146xx",
#QT_TR_NOOP("Weather Channel-HAFA"):"0001000248414641",
#QT_TR_NOOP("News Channel-HAGx"):"00010002484147xx",
#QT_TR_NOOP("News Channel-HAGA"):"0001000248414741"
}
#idDict = {}
#for title in TitleDict:
# idDict[TitleDict[title]] = title
IOSdict = {}
for title in TitleDict:
if re.search("IOS", title):
IOSdict[title] = TitleDict[title]
IOSdict["IOS202"] = "00000001000000ca"
IOSdict["IOS222"] = "00000001000000de"
IOSdict["IOS249"] = "00000001000000f9"
IOSids = {}
for ios in IOSdict:
IOSids[IOSdict[ios]] = ios
def AsciiID(channelname):
return binascii.unhexlify(TitleDict[channelname][7:])
if __name__ == "__main__":
print TitleDict["System Menu"]
print TitleDict["Mii Channel"][7:]
print AsciiID("Mii Channel")
print idDict["0001000248414741"]

282
WiiPy/Struct.py Normal file
View File

@ -0,0 +1,282 @@
import struct, sys
class StructType(tuple):
def __getitem__(self, value):
return [self] * value
def __call__(self, value, endian='<'):
if isinstance(value, str):
return struct.unpack(endian + tuple.__getitem__(self, 0), value[:tuple.__getitem__(self, 1)])[0]
else:
return struct.pack(endian + tuple.__getitem__(self, 0), value)
class StructException(Exception):
pass
class Struct(object):
__slots__ = ('__attrs__', '__baked__', '__defs__', '__endian__', '__next__', '__sizes__', '__values__')
int8 = StructType(('b', 1))
uint8 = StructType(('B', 1))
int16 = StructType(('h', 2))
uint16 = StructType(('H', 2))
int32 = StructType(('l', 4))
uint32 = StructType(('L', 4))
int64 = StructType(('q', 8))
uint64 = StructType(('Q', 8))
float = StructType(('f', 4))
@classmethod
def string(cls, len, offset=0, encoding=None, stripNulls=False, value=''):
return StructType(('string', (len, offset, encoding, stripNulls, value)))
LE = '<'
BE = '>'
__endian__ = '<'
def __init__(self, func=None, unpack=None, **kwargs):
self.__defs__ = []
self.__sizes__ = []
self.__attrs__ = []
self.__values__ = {}
self.__next__ = True
self.__baked__ = False
if func == None:
self.__format__()
else:
sys.settrace(self.__trace__)
func()
for name in func.func_code.co_varnames:
value = self.__frame__.f_locals[name]
self.__setattr__(name, value)
self.__baked__ = True
if unpack != None:
if isinstance(unpack, tuple):
self.unpack(*unpack)
else:
self.unpack(unpack)
if len(kwargs):
for name in kwargs:
self.__values__[name] = kwargs[name]
def __trace__(self, frame, event, arg):
self.__frame__ = frame
sys.settrace(None)
def __setattr__(self, name, value):
if name in self.__slots__:
return object.__setattr__(self, name, value)
if self.__baked__ == False:
if not isinstance(value, list):
value = [value]
attrname = name
else:
attrname = '*' + name
self.__values__[name] = None
for sub in value:
if isinstance(sub, Struct):
sub = sub.__class__
try:
if issubclass(sub, Struct):
sub = ('struct', sub)
except TypeError:
pass
type_, size = tuple(sub)
if type_ == 'string':
self.__defs__.append(Struct.string)
self.__sizes__.append(size)
self.__attrs__.append(attrname)
self.__next__ = True
if attrname[0] != '*':
self.__values__[name] = size[3]
elif self.__values__[name] == None:
self.__values__[name] = [size[3] for val in value]
elif type_ == 'struct':
self.__defs__.append(Struct)
self.__sizes__.append(size)
self.__attrs__.append(attrname)
self.__next__ = True
if attrname[0] != '*':
self.__values__[name] = size()
elif self.__values__[name] == None:
self.__values__[name] = [size() for val in value]
else:
if self.__next__:
self.__defs__.append('')
self.__sizes__.append(0)
self.__attrs__.append([])
self.__next__ = False
self.__defs__[-1] += type_
self.__sizes__[-1] += size
self.__attrs__[-1].append(attrname)
if attrname[0] != '*':
self.__values__[name] = 0
elif self.__values__[name] == None:
self.__values__[name] = [0 for val in value]
else:
try:
self.__values__[name] = value
except KeyError:
raise AttributeError(name)
def __getattr__(self, name):
if self.__baked__ == False:
return name
else:
try:
return self.__values__[name]
except KeyError:
raise AttributeError(name)
def __len__(self):
ret = 0
arraypos, arrayname = None, None
for i in range(len(self.__defs__)):
sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i]
if sdef == Struct.string:
size, offset, encoding, stripNulls, value = size
if isinstance(size, str):
size = self.__values__[size] + offset
elif sdef == Struct:
if attrs[0] == '*':
if arrayname != attrs:
arrayname = attrs
arraypos = 0
size = len(self.__values__[attrs[1:]][arraypos])
size = len(self.__values__[attrs])
ret += size
return ret
def unpack(self, data, pos=0):
for name in self.__values__:
if not isinstance(self.__values__[name], Struct):
self.__values__[name] = None
elif self.__values__[name].__class__ == list and len(self.__values__[name]) != 0:
if not isinstance(self.__values__[name][0], Struct):
self.__values__[name] = None
arraypos, arrayname = None, None
for i in range(len(self.__defs__)):
sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i]
if sdef == Struct.string:
size, offset, encoding, stripNulls, value = size
if isinstance(size, str):
size = self.__values__[size] + offset
temp = data[pos:pos+size]
if len(temp) != size:
raise StructException('Expected %i byte string, got %i' % (size, len(temp)))
if encoding != None:
temp = temp.decode(encoding)
if stripNulls:
temp = temp.rstrip('\0')
if attrs[0] == '*':
name = attrs[1:]
if self.__values__[name] == None:
self.__values__[name] = []
self.__values__[name].append(temp)
else:
self.__values__[attrs] = temp
pos += size
elif sdef == Struct:
if attrs[0] == '*':
if arrayname != attrs:
arrayname = attrs
arraypos = 0
name = attrs[1:]
self.__values__[attrs][arraypos].unpack(data, pos)
pos += len(self.__values__[attrs][arraypos])
arraypos += 1
else:
self.__values__[attrs].unpack(data, pos)
pos += len(self.__values__[attrs])
else:
values = struct.unpack(self.__endian__+sdef, data[pos:pos+size])
pos += size
j = 0
for name in attrs:
if name[0] == '*':
name = name[1:]
if self.__values__[name] == None:
self.__values__[name] = []
self.__values__[name].append(values[j])
else:
self.__values__[name] = values[j]
j += 1
return self
def pack(self):
arraypos, arrayname = None, None
ret = ''
for i in range(len(self.__defs__)):
sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i]
if sdef == Struct.string:
size, offset, encoding, stripNulls, value = size
if isinstance(size, str):
size = self.__values__[size]+offset
if attrs[0] == '*':
if arrayname != attrs:
arraypos = 0
arrayname = attrs
temp = self.__values__[attrs[1:]][arraypos]
arraypos += 1
else:
temp = self.__values__[attrs]
if encoding != None:
temp = temp.encode(encoding)
temp = temp[:size]
ret += temp + ('\0' * (size - len(temp)))
elif sdef == Struct:
if attrs[0] == '*':
if arrayname != attrs:
arraypos = 0
arrayname = attrs
ret += self.__values__[attrs[1:]][arraypos].pack()
arraypos += 1
else:
ret += self.__values__[attrs].pack()
else:
values = []
for name in attrs:
if name[0] == '*':
if arrayname != name:
arraypos = 0
arrayname = name
values.append(self.__values__[name[1:]][arraypos])
arraypos += 1
else:
values.append(self.__values__[name])
ret += struct.pack(self.__endian__+sdef, *values)
return ret
def __getitem__(self, value):
return [('struct', self.__class__)] * value

22
WiiPy/Wii.py Normal file
View File

@ -0,0 +1,22 @@
__all__ = []
from common import *
from formats import *
from title import *
from disc import *
from image import *
from archive import *
from export import *
from compression import *
from nand import *
from headers import *
from bns import *
if (__name__ == "__main__"):
Crypto()
TMD()
Ticket()
#insert non-dependant check code here
print("\nAll Wii.py components loaded sucessfully!\n")

1
WiiPy/__init__.py Normal file
View File

@ -0,0 +1 @@

454
WiiPy/archive.py Normal file
View File

@ -0,0 +1,454 @@
from common import *
from title import *
import zlib
class U8(WiiArchive):
"""This class can unpack and pack U8 archives, which are used all over the Wii. They are often used in Banners and contents in Downloadable Titles. Please remove all headers and compression first, kthx.
The f parameter is either the source folder to pack, or the source file to unpack."""
class U8Header(Struct):
__endian__ = Struct.BE
def __format__(self):
self.tag = Struct.string(4)
self.rootnode_offset = Struct.uint32
self.header_size = Struct.uint32
self.data_offset = Struct.uint32
self.zeroes = Struct.string(16)
class U8Node(Struct):
__endian__ = Struct.BE
def __format__(self):
self.type = Struct.uint16
self.name_offset = Struct.uint16
self.data_offset = Struct.uint32
self.size = Struct.uint32
def __init__(self):
self.files = []
def _dump(self):
header = self.U8Header()
rootnode = self.U8Node()
# constants
header.tag = "U\xAA8-"
header.rootnode_offset = 0x20
header.zeroes = "\x00" * 16
rootnode.type = 0x0100
nodes = []
strings = "\x00"
data = ''
for item, value in self.files:
node = self.U8Node()
recursion = item.count('/')
if(recursion < 0):
recursion = 0
name = item[item.rfind('/') + 1:]
node.name_offset = len(strings)
strings += name + '\x00'
if(value == None):
node.type = 0x0100
node.data_offset = recursion
node.size = len(nodes)
for one, two in self.files:
if(one[:len(item)] == item): # find nodes in the folder
node.size += 1
node.size += 1
else:
sz = len(value)
node.data_offset = len(data)
data += value + "\x00" * (align(sz, 32) - sz) # 32 seems to work best for fuzzyness? I'm still really not sure
node.size = sz
node.type = 0x0000
nodes.append(node)
header.header_size = ((len(nodes) + 1) * len(rootnode)) + len(strings)
header.data_offset = align(header.header_size + header.rootnode_offset, 64)
rootnode.size = len(nodes) + 1
for i in range(len(nodes)):
if(nodes[i].type == 0x0000):
nodes[i].data_offset += header.data_offset
fd = ''
fd += header.pack()
fd += rootnode.pack()
for nodeobj in nodes:
fd += nodeobj.pack()
fd += strings
fd += "\x00" * (header.data_offset - header.rootnode_offset - header.header_size)
fd += data
return fd
def _dumpDir(self, dir):
if(not os.path.isdir(dir)):
os.mkdir(dir)
old = os.getcwd()
os.chdir(dir)
for item, data in self.files:
if(data == None):
if(not os.path.isdir(item)):
os.mkdir(item)
else:
open(item, "wb").write(data)
os.chdir(old)
def _loadDir(self, dir):
try:
self._tmpPath += ''
except:
self._tmpPath = ''
old = os.getcwd()
os.chdir(dir)
entries = os.listdir(".")
for entry in entries:
if(os.path.isdir(entry)):
self.files.append((self._tmpPath + entry, None))
self._tmpPath += entry + '/'
self._loadDir(entry)
elif(os.path.isfile(entry)):
data = open(entry, "rb").read()
self.files.append((self._tmpPath + entry, data))
os.chdir(old)
self._tmpPath = self._tmpPath[:self._tmpPath.find('/') + 1]
def _load(self, data):
offset = 0
header = self.U8Header()
header.unpack(data[offset:offset + len(header)])
offset += len(header)
assert header.tag == "U\xAA8-"
offset = header.rootnode_offset
rootnode = self.U8Node()
rootnode.unpack(data[offset:offset + len(rootnode)])
offset += len(rootnode)
nodes = []
for i in range(rootnode.size - 1):
node = self.U8Node()
node.unpack(data[offset:offset + len(node)])
offset += len(node)
nodes.append(node)
strings = data[offset:offset + header.data_offset - len(header) - (len(rootnode) * rootnode.size)]
offset += len(strings)
recursion = [rootnode.size]
recursiondir = []
counter = 0
for node in nodes:
counter += 1
name = strings[node.name_offset:].split('\0', 1)[0]
if(node.type == 0x0100): # folder
recursion.append(node.size)
recursiondir.append(name)
assert len(recursion) == node.data_offset + 2 # haxx
self.files.append(('/'.join(recursiondir), None))
elif(node.type == 0): # file
self.files.append(('/'.join(recursiondir) + '/' + name, data[node.data_offset:node.data_offset + node.size]))
offset += node.size
else: # unknown type -- wtf?
pass
sz = recursion.pop()
if(sz != counter + 1):
recursion.append(sz)
else:
recursiondir.pop()
def __str__(self):
ret = ''
for key, value in self.files:
name = key[key.rfind('/') + 1:]
recursion = key.count('/')
ret += ' ' * recursion
if(value == None):
ret += '[' + name + ']'
else:
ret += name
ret += '\n'
return ret
def __getitem__(self, key):
for item, val in self.files:
if(item == key):
if(val != None):
return val
else:
ret = []
for item2, val2 in self.files:
if(item2.find(item) == 0):
ret.append(item2[len(item) + 1:])
return ret[1:]
raise KeyError
def __setitem__(self, key, val):
for i in range(len(self.files)):
if(self.files[i][0] == key):
self.files[i] = (self.files[i][0], val)
return
self.files.append((key, val))
class WAD(WiiArchive):
def __init__(self, boot2 = False):
self.tmd = TMD()
self.tik = Ticket()
self.contents = []
self.boot2 = False
self.cert = ""
def _load(self, data):
if(self.boot2 != True):
headersize, wadtype, certsize, reserved, tiksize, tmdsize, datasize, footersize, padding = struct.unpack('>I4s6I32s', data[:64])
pos = 64
else:
headersize, data_offset, certsize, tiksize, tmdsize, padding = struct.unpack('>IIIII12s', data[:32])
pos = 32
rawcert = data[pos:pos + certsize]
pos += certsize
if(self.boot2 != True):
if(certsize % 64 != 0):
pos += 64 - (certsize % 64)
self.cert = rawcert
rawtik = data[pos:pos + tiksize]
pos += tiksize
if(self.boot2 != True):
if(tiksize % 64 != 0):
pos += 64 - (tiksize % 64)
self.tik = Ticket.load(rawtik)
rawtmd = data[pos:pos + tmdsize]
pos += tmdsize
if(self.boot2 == True):
pos = data_offset
else:
pos += 64 - (tmdsize % 64)
self.tmd = TMD.load(rawtmd)
titlekey = self.tik.getTitleKey()
contents = self.tmd.getContents()
for i in range(0, len(contents)):
tmpsize = contents[i].size
if(tmpsize % 16 != 0):
tmpsize += 16 - (tmpsize % 16)
encdata = data[pos:pos + tmpsize]
pos += tmpsize
decdata = Crypto().decryptContent(titlekey, contents[i].index, encdata)
self.contents.append(decdata)
if(tmpsize % 64 != 0):
pos += 64 - (tmpsize % 64)
def _loadDir(self, dir):
origdir = os.getcwd()
os.chdir(dir)
self.tmd = TMD.loadFile("tmd")
self.tik = Ticket.loadFile("tik")
self.cert = open("cert", "rb").read()
contents = self.tmd.getContents()
for i in range(len(contents)):
self.contents.append(open("%08x.app" % i, "rb").read())
os.chdir(origdir)
def _dumpDir(self, dir):
origdir = os.getcwd()
os.chdir(dir)
contents = self.tmd.getContents()
for i in range(len(contents)):
open("%08x.app" % i, "wb").write(self.contents[i])
self.tmd.dumpFile("tmd")
self.tik.dumpFile("tik")
open("cert", "wb").write(self.cert)
os.chdir(origdir)
def _dump(self, fakesign = True):
titlekey = self.tik.getTitleKey()
contents = self.tmd.getContents()
apppack = ""
for i, content in enumerate(contents):
if(fakesign):
content.hash = str(Crypto().createSHAHash(self.contents[content.index]))
content.size = len(self.contents[content.index])
encdata = Crypto().encryptContent(titlekey, content.index, self.contents[content.index])
apppack += encdata
if(len(encdata) % 64 != 0):
apppack += "\x00" * (64 - (len(encdata) % 64))
if(fakesign):
self.tmd.setContents(contents)
self.tmd.fakesign()
self.tik.fakesign()
rawtmd = self.tmd.dump()
rawcert = self.cert
rawtik = self.tik.dump()
sz = 0
for i in range(len(contents)):
sz += contents[i].size
if(sz % 64 != 0):
sz += 64 - (contents[i].size % 64)
if(self.boot2 != True):
pack = struct.pack('>I4s6I', 32, "Is\x00\x00", len(rawcert), 0, len(rawtik), len(rawtmd), sz, 0)
pack += "\x00" * 32
else:
pack = struct.pack('>IIIII12s', 32, align(len(rawcert) + len(rawtik) + len(rawtmd), 0x40), len(rawcert), len(rawtik), len(rawtmd), "\x00" * 12)
pack += rawcert
if(len(rawcert) % 64 != 0 and self.boot2 != True):
pack += "\x00" * (64 - (len(rawcert) % 64))
pack += rawtik
if(len(rawtik) % 64 != 0 and self.boot2 != True):
pack += "\x00" * (64 - (len(rawtik) % 64))
pack += rawtmd
if(len(rawtmd) % 64 != 0 and self.boot2 != True):
pack += "\x00" * (64 - (len(rawtmd) % 64))
if(self.boot2 == True):
pack += "\x00" * (align(len(rawcert) + len(rawtik) + len(rawtmd), 0x40) - (len(rawcert) + len(rawtik) + len(rawtmd)))
pack += apppack
return pack
def __getitem__(self, idx):
return self.contents[idx]
def __setitem__(self, idx, value):
self.contents[idx] = value
def __str__(self):
out = ""
out += "Wii WAD:\n"
out += str(self.tmd)
out += str(self.tik)
return out
class CCF():
class CCFHeader(Struct):
__endian__ = Struct.LE
def __format__(self):
self.magic = Struct.string(4)
self.zeroes12 = Struct.string(12)
self.rootOffset = Struct.uint32
self.filesCount = Struct.uint32
self.zeroes8 = Struct.string(8)
class CCFFile(Struct):
__endian__ = Struct.LE
def __format__(self):
self.fileName = Struct.string(20)
self.fileOffset = Struct.uint32
self.fileSize = Struct.uint32
self.fileSizeDecompressed = Struct.uint32
def __init__(self, fileName):
self.fileName = fileName
self.fd = open(fileName, 'r+b')
def compress(self, folder):
fileList = []
fileHdr = self.CCFHeader()
files = os.listdir(folder)
fileHdr.magic = "\x43\x43\x46\x00"
fileHdr.zeroes12 = '\x00' * 12
fileHdr.rootOffset = 0x20
fileHdr.zeroes8 = '\x00' * 8
currentOffset = len(fileHdr)
packedFiles = 0
previousFileEndOffset = 0
for file in files:
if os.path.isdir(folder + '/' + file) or file == '.DS_Store':
continue
else:
fileList.append(file)
fileHdr.filesCount = len(fileList)
self.fd.write(fileHdr.pack())
self.fd.write('\x00' * (fileHdr.filesCount * len(self.CCFFile())))
for fileNumber in range(len(fileList)):
fileEntry = self.CCFFile()
compressedBuffer = zlib.compress(open(folder + '/' + fileList[fileNumber]).read())
fileEntry.fileName = fileList[fileNumber]
fileEntry.fileSize = len(compressedBuffer)
fileEntry.fileSizeDecompressed = os.stat(folder + '/' + fileList[fileNumber]).st_size
fileEntry.fileOffset = align(self.fd.tell(), 32) / 32
print 'File {0} ({1}Kb) placed at offset 0x{2:X}'.format(fileEntry.fileName, fileEntry.fileSize / 1024, fileEntry.fileOffset * 32)
self.fd.seek(len(fileHdr) + fileNumber * len(self.CCFFile()))
self.fd.write(fileEntry.pack())
self.fd.seek(fileEntry.fileOffset * 32)
self.fd.write(compressedBuffer)
self.fd.close()
def decompress(self):
fileHdr = self.CCFHeader()
hdrData = self.fd.read(len(fileHdr))
fileHdr.unpack(hdrData)
print 'Found {0} file/s and root node at 0x{1:X}'.format(fileHdr.filesCount, fileHdr.rootOffset)
if fileHdr.magic != "\x43\x43\x46\x00":
raise ValueError("Wrong magic, 0x{0}".format(fileHdr.magic))
try:
os.mkdir(os.path.dirname(self.fileName) + '/' + self.fd.name.replace(".", "_") + "_out")
except:
pass
os.chdir(os.path.dirname(self.fileName) + '/' + self.fd.name.replace(".", "_") + "_out")
currentOffset = len(fileHdr)
for x in range(fileHdr.filesCount):
self.fd.seek(currentOffset)
fileEntry = self.CCFFile()
fileData = self.fd.read(len(fileEntry))
fileEntry.unpack(fileData)
fileEntry.fileOffset = fileEntry.fileOffset * 32
print 'File {0} at offset 0x{1:X}'.format(fileEntry.fileName, fileEntry.fileOffset)
print 'File size {0}Kb ({1}Kb decompressed)'.format(fileEntry.fileSize / 1024, fileEntry.fileSizeDecompressed / 1024)
output = open(fileEntry.fileName.rstrip('\0'), 'w+b')
self.fd.seek(fileEntry.fileOffset)
if fileEntry.fileSize == fileEntry.fileSizeDecompressed:
print 'The file is stored uncompressed'
output.write(self.fd.read(fileEntry.fileSize))
else:
print 'The file is stored compressed..decompressing'
decompressedBuffer = zlib.decompress(self.fd.read(fileEntry.fileSize))
output.write(decompressedBuffer)
output.close()
currentOffset += len(fileEntry)
if(__name__ == '__main__'):
wad = WAD.loadFile("testing.wad")
print wad
wad.dumpDir("outdir")
wad.dumpFile("interesting.wad", fakesign = False) #keyword arguements work as expected when calling _dump(). awesome.
wad2 = WAD.loadDir("outdir")
print wad2
wad3 = WAD.loadFile("interesting.wad")
print wad3
wad3.dumpDir("outdir2")

618
WiiPy/bns.py Normal file
View File

@ -0,0 +1,618 @@
#!/usr/bin/python
from common import *
class SoundFile:
def __init__(self, signal, filename, samplerate=32000):
self.actual_file = StringIO()
self.file = wave.open(filename, 'wb')
self.signal = signal
self.sr = samplerate
def write(self):
self.file.setparams((2, 2, self.sr, self.sr*4, 'NONE', 'noncompressed'))
self.file.writeframes(self.signal)
self.actual_file.seek(0)
self.file.close()
class BNS_data(object):
def __init__(self):
self.magic = "DATA"
self.size = 0x0004d000
def eat(self, buffer, offset):
self.magic, self.size = struct.unpack('>4sI', buffer[offset:offset+8])
return offset + 8
def show(self):
print "Magic: %s" % self.magic
print "Length: %08x" % self.size
return
def write(self, file):
file.write(self.magic)
file.write(struct.pack('>I', self.size))
file.write(self.data)
return
class BNS_info(object):
def __init__(self):
self.magic = "INFO"
self.size = 0x000000a0
self.codec = 0x00
self.has_loop = 0x00
self.chan_cnt = 0x02
self.zero = 0x00
self.samplerate = 0xac44
self.pad0 = 0x0000
self.loop_start = 0x00000000
self.loop_end = 0x00000000
self.offset_to_chan_starts = 0x00000018
self.pad2 = 0x00000000
self.channel1_start_offset = 0x00000020
self.channel2_start_offset = 0x0000002C
self.chan1_start = 0x00000000
self.coefficients1_offset = 0x0000038
self.pad1 = 0x00000000
self.chan2_start = 0x00000000
self.coefficients2_offset = 0x00000068
self.pad3 = 0x00000000
self.coefficients1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
self.chan1_gain = 0x0000
self.chan1_predictive_scale = 0x0000
self.chan1_previous_value = 0x0000
self.chan1_next_previous_value = 0x0000
self.chan1_loop_predictive_scale = 0x0000
self.chan1_loop_previous_value = 0x0000
self.chan1_loop_next_previous_value = 0x0000
self.chan1_loop_padding = 0x0000
self.coefficients2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
self.chan2_gain = 0x0000
self.chan2_predictive_scale = 0x0000
self.chan2_previous_value = 0x0000
self.chan2_next_previous_value = 0x0000
self.chan2_loop_predictive_scale = 0x0000
self.chan2_loop_previous_value = 0x0000
self.chan2_loop_next_previous_value = 0x0000
self.chan2_loop_padding = 0x0000
def eat(self, buffer, offset):
self.magic, self.size = struct.unpack('>4sI', buffer[offset+0:offset+8])
self.codec, self.has_loop = struct.unpack('>BB', buffer[offset+8:offset+10])
self.chan_cnt, self.zero = struct.unpack('>BB', buffer[offset+10:offset+12])
self.samplerate, self.pad0 = struct.unpack('>HH', buffer[offset+12:offset+16])
assert self.samplerate <= 48000
assert self.samplerate > 32000
self.loop_start, self.loop_end = struct.unpack('>II', buffer[offset+16:offset+24])
co = offset + 24
self.offset_to_chan_starts = Struct.uint32(buffer[co:co+4], endian='>')
co += 4
self.pad2 = Struct.uint32(buffer[co:co+4], endian='>')
co += 4
self.channel1_start_offset = Struct.uint32(buffer[co:co+4], endian='>')
co += 4
self.channel2_start_offset = Struct.uint32(buffer[co:co+4], endian='>')
co += 4
self.chan1_start = Struct.uint32(buffer[co:co+4], endian='>')
co += 4
self.coefficients1_offset = Struct.uint32(buffer[co:co+4], endian='>')
co += 4
if self.chan_cnt == 2:
self.pad1 = Struct.uint32(buffer[co:co+4], endian='>')
co += 4
self.chan2_start = Struct.uint32(buffer[co:co+4], endian='>')
co += 4
self.coefficients2_offset = Struct.uint32(buffer[co:co+4], endian='>')
co += 4
self.pad3 = Struct.uint32(buffer[co:co+4], endian='>')
co += 4
for x in xrange(16):
self.coefficients1[x] = Struct.int16(buffer[co:co+2], endian='>')
co += 2
self.chan1_gain = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_predictive_scale = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_next_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_loop_predictive_scale = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_loop_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_loop_next_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_loop_padding = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
for x in xrange(16):
self.coefficients2[x] = Struct.int16(buffer[co:co+2], endian='>')
co += 2
self.chan2_gain = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan2_predictive_scale = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan2_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan2_next_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan2_loop_predictive_scale = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan2_loop_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan2_loop_next_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan2_loop_padding = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
elif self.chan_cnt == 1:
for x in xrange(16):
self.coefficients1[x] = Struct.int16(buffer[co:co+2], endian='>')
co += 2
self.chan1_gain = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_predictive_scale = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_next_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_loop_predictive_scale = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_loop_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_loop_next_previous_value = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
self.chan1_loop_padding = Struct.uint16(buffer[co:co+2], endian='>')
co += 2
return co
def show(self):
print "Magic: %s" % self.magic
print "Length: %08x" % self.size
print "Codec: %02x " % self.codec,
if self.codec == 0: print "ADPCM"
else: print "Unknown (Maybe >_>, please contact megazig)"
print "Loop Flag: %02x " % self.has_loop,
if self.has_loop == 0: print "One shot"
else: print "Looping"
print "Channel Count: %02x" % self.chan_cnt
print "Zero: %02x" % self.zero
print "Samplerate: %04x %d" % ( self.samplerate , self.samplerate )
print "Padding: %04x" % self.pad0
print "Loop Start: %08x" % self.loop_start
print "Loop End: %08x" % self.loop_end
print "Channels Starts Offsets: %08x" % self.offset_to_chan_starts
print "Padding: %08x" % self.pad2
print "Channel 1 Start Offset: %08x" % self.channel1_start_offset
print "Channel 2 Start Offset: %08x" % self.channel2_start_offset
print "Channel 1 Start: %08x" % self.chan1_start
print "Coefficients 1 Offset: %08x" % self.coefficients1_offset
if self.chan_cnt == 2:
print "Padding: %08x" % self.pad1
print "Channel 2 Start: %08x" % self.chan2_start
print "Coefficients 2 Offset: %08x" % self.coefficients2_offset
print "Padding: %08x" % self.pad3
for x in xrange(16):
print "\t\tCoefficients 1: %2d - %04x - %d" % ( x , self.coefficients1[x], self.coefficients1[x] )
print "\tGain: %04x" % self.chan1_gain
print "\tPredictive Scale: %04x" % self.chan1_predictive_scale
print "\tPrevious Value: %04x" % self.chan1_previous_value
print "\tNext Previous Value: %04x" % self.chan1_next_previous_value
print "\tLoop Predictive Scale: %04x" % self.chan1_loop_predictive_scale
print "\tLoop Previous Value: %04x" % self.chan1_loop_previous_value
print "\tLoop Next Previous Value: %04x" % self.chan1_loop_next_previous_value
print "\tPadding: %04x" % self.chan1_loop_padding
for x in xrange(16):
print "\t\tCoefficients 2: %2d - %04x - %d" % ( x , self.coefficients2[x], self.coefficients2[x] )
print "\tGain: %04x" % self.chan2_gain
print "\tPredictive Scale: %04x" % self.chan2_predictive_scale
print "\tPrevious Value: %04x" % self.chan2_previous_value
print "\tNext Previous Value: %04x" % self.chan2_next_previous_value
print "\tLoop Predictive Scale: %04x" % self.chan2_loop_predictive_scale
print "\tLoop Previous Value: %04x" % self.chan2_loop_previous_value
print "\tLoop Next Previous Value: %04x" % self.chan2_loop_next_previous_value
print "\tPadding: %04x" % self.chan2_loop_padding
elif self.chan_cnt == 1:
for x in xrange(16):
print "\t\tCoefficients 1: %2d - %04x - %d" % ( x , self.coefficients1[x], self.coefficients1[x] )
print "\tGain: %04x" % self.chan1_gain
print "\tPredictive Scale: %04x" % self.chan1_predictive_scale
print "\tPrevious Value: %04x" % self.chan1_previous_value
print "\tNext Previous Value: %04x" % self.chan1_next_previous_value
print "\tLoop Predictive Scale: %04x" % self.chan1_loop_predictive_scale
print "\tLoop Previous Value: %04x" % self.chan1_loop_previous_value
print "\tLoop Next Previous Value: %04x" % self.chan1_loop_next_previous_value
print "\tPadding: %04x" % self.chan1_loop_padding
return
def write(self, file):
file.write(self.magic)
file.write(struct.pack('>I', self.size))
file.write(struct.pack('>B', self.codec))
file.write(struct.pack('>B', self.has_loop))
file.write(struct.pack('>B', self.chan_cnt))
file.write(struct.pack('>B', self.zero))
file.write(struct.pack('>H', self.samplerate))
file.write(struct.pack('>H', self.pad0))
file.write(struct.pack('>I', self.loop_start))
file.write(struct.pack('>I', self.loop_end))
file.write(struct.pack('>I', self.offset_to_chan_starts))
file.write(struct.pack('>I', self.pad2))
file.write(struct.pack('>I', self.channel1_start_offset))
file.write(struct.pack('>I', self.channel2_start_offset))
file.write(struct.pack('>I', self.chan1_start))
file.write(struct.pack('>I', self.coefficients1_offset))
if self.chan_cnt == 2:
file.write(struct.pack('>I', self.pad1))
file.write(struct.pack('>I', self.chan2_start))
file.write(struct.pack('>I', self.coefficients2_offset))
file.write(struct.pack('>I', self.pad3))
for x in xrange(16):
file.write(struct.pack('>h', self.coefficients1[x]))
file.write(struct.pack('>H', self.chan1_gain))
file.write(struct.pack('>H', self.chan1_predictive_scale))
file.write(struct.pack('>H', self.chan1_previous_value))
file.write(struct.pack('>H', self.chan1_next_previous_value))
file.write(struct.pack('>H', self.chan1_loop_predictive_scale))
file.write(struct.pack('>H', self.chan1_loop_previous_value))
file.write(struct.pack('>H', self.chan1_loop_next_previous_value))
file.write(struct.pack('>H', self.chan1_loop_padding))
for x in xrange(16):
file.write(struct.pack('>h', self.coefficients2[x]))
file.write(struct.pack('>H', self.chan2_gain))
file.write(struct.pack('>H', self.chan2_predictive_scale))
file.write(struct.pack('>H', self.chan2_previous_value))
file.write(struct.pack('>H', self.chan2_next_previous_value))
file.write(struct.pack('>H', self.chan2_loop_predictive_scale))
file.write(struct.pack('>H', self.chan2_loop_previous_value))
file.write(struct.pack('>H', self.chan2_loop_next_previous_value))
file.write(struct.pack('>H', self.chan2_loop_padding))
elif self.chan_cnt == 1:
for x in xrange(16):
file.write(struct.pack('>h', self.coefficients1[x]))
file.write(struct.pack('>H', self.chan1_gain))
file.write(struct.pack('>H', self.chan1_predictive_scale))
file.write(struct.pack('>H', self.chan1_previous_value))
file.write(struct.pack('>H', self.chan1_next_previous_value))
file.write(struct.pack('>H', self.chan1_loop_predictive_scale))
file.write(struct.pack('>H', self.chan1_loop_previous_value))
file.write(struct.pack('>H', self.chan1_loop_next_previous_value))
file.write(struct.pack('>H', self.chan1_loop_padding))
return
class BNS_header(object):
def __init__(self):
self.magic = "BNS "
self.flags = 0xfeff0100
self.filesize = 0x0004d0c0
self.size = 0x0020
self.chunk_cnt = 0x0002
self.info_off = 0x00000020
self.info_len = 0x000000a0
self.data_off = 0x000000c0
self.data_len = 0x0004d000
def eat(self, buffer, offset):
if struct.unpack('>4s', buffer[offset:offset+4])[0] != "BNS ":
offset += 0x20
self.magic, self.flags = struct.unpack('>4sI', buffer[offset+0:offset+8])
self.filesize, self.size, self.chunk_cnt = struct.unpack('>IHH', buffer[offset+8:offset+16])
self.info_off, self.info_len = struct.unpack('>II', buffer[offset+16:offset+24])
self.data_off, self.data_len = struct.unpack('>II', buffer[offset+24:offset+32])
assert self.magic == "BNS "
assert self.info_off < self.filesize
assert self.data_off < self.filesize
return offset + 32
def show(self):
print "Magic: %s" % self.magic
print "Flags: %08x" % self.flags
print "Length: %08x" % self.filesize
print "Header Size: %04x" % self.size
print "Chunk Count: %04x" % self.chunk_cnt
print "Info Offset: %08x" % self.info_off
print "Info Length: %08x" % self.info_len
print "Data Offset: %08x" % self.data_off
print "Data Length: %08x" % self.data_len
return
def write(self, file):
file.write(self.magic)
file.write(struct.pack('>I', self.flags))
file.write(struct.pack('>I', self.filesize))
file.write(struct.pack('>H', self.size))
file.write(struct.pack('>H', self.chunk_cnt))
file.write(struct.pack('>I', self.info_off))
file.write(struct.pack('>I', self.info_len))
file.write(struct.pack('>I', self.data_off))
file.write(struct.pack('>I', self.data_len))
return
class BNS(object):
def __init__(self):
self.header = BNS_header()
self.info = BNS_info()
self.data = BNS_data()
self.buffered_data = ""
self.lsamps = [ [ 0 , 0 ] , [ 0 , 0 ] ]
self.rlsamps = [ [ 0 , 0 ] , [ 0 , 0 ] ]
self.tlsamps = [ 0 , 0 ]
self.hbc_deftbl = [ 674 , 1040,
3598, -1738,
2270, -583,
3967, -1969,
1516, 381,
3453, -1468,
2606, -617,
3795, -1759 ]
self.deftbl = [ 1820 , -856 ,
3238 , -1514 ,
2333 , -550 ,
3336 , -1376 ,
2444 , -949 ,
3666 , -1764 ,
2654 , -701 ,
3420 , -1398 ]
self.phist1 = [ 0 , 0 ]
self.phist2 = [ 0 , 0 ]
self.errors = 0
def find_exp(self, residual):
exp = 0
while residual>7.5 or residual<-8.5:
exp += 1
residual /= 2.0
return exp
def determine_std_exponent(self, idx, table, index, inbuf):
elsamps = [ 0 , 0 ]
max_res = 0
factor1 = table[2*index+0]
factor2 = table[2*index+1]
for x in xrange(2):
elsamps[x] = self.rlsamps[idx][x]
for i in xrange(14):
predictor = (elsamps[1]*factor1 + elsamps[0]*factor2) >> 11
residual = inbuf[i] - predictor
if residual>max_res:
max_res = residual
elsamps[0] = elsamps[1]
elsamps[1] = inbuf[i]
return self.find_exp(max_res)
def compress_adpcm(self, idx, table, tblidx, inbuf):
data = [0 for i in range(8)]
error = 0
factor1 = table[2*tblidx+0]
factor2 = table[2*tblidx+1]
exp = self.determine_std_exponent(idx, table, tblidx, inbuf)
while exp<=15:
error = 0
data[0] = exp | (tblidx << 4)
for x in xrange(2):
self.tlsamps[x] = self.rlsamps[idx][x]
j = 0
for i in xrange(14):
predictor = (self.tlsamps[1]*factor1 + self.tlsamps[0]*factor2) >> 11
residual = inbuf[i] - predictor
residual = residual >> exp
if residual>7 or residual<-8:
exp += 1
break
nibble = clamp(residual, -8, 7)
if i&1:
data[i/2+1] = data[i/2+1] | (nibble & 0xf)
else:
data[i/2+1] = nibble << 4
predictor = predictor + (nibble << exp)
self.tlsamps[0] = self.tlsamps[1]
self.tlsamps[1] = clamp(predictor, -32768, 32767)
error = error + ((self.tlsamps[1] - inbuf[i]) ** 2)
else:
j = 14
if j == 14:
break
return error, data
def repack_adpcm(self, idx, table, inbuf):
data = [0 for i in range(8)]
blsamps = [ 0 , 0 ]
bestidx = -1
besterror = 999999999.0
for tblidx in xrange(8):
error, testdata = self.compress_adpcm(idx, table, tblidx, inbuf)
if error < besterror:
besterror = error
for x in xrange(8):
data[x] = testdata[x]
for x in xrange(2):
blsamps[x] = self.tlsamps[x]
bestidx = tblidx
for x in xrange(2):
self.rlsamps[idx][x] = blsamps[x]
return data
def encode(self, buffer, offset=0):
sampsbuf = [0 for i in range(14)]
templen = len(buffer)
templen = templen / 4
modlen = templen % 14
for x in xrange(14-modlen):
buffer = buffer + '\x00'
buffer = buffer + '\x00'
buffer = buffer + '\x00'
buffer = buffer + '\x00'
num_samps = len(buffer) / 4
blocks = (num_samps + 13) / 14
snddatal = []
snddatar = []
co = offset
temp = 0
for x in xrange(num_samps):
snddatal.append(Struct.int16(buffer[co:co+2]))
co += 2
snddatar.append(Struct.int16(buffer[co:co+2]))
co += 2
data = [0 for i in range(blocks*16)]
data1_off = 0
data2_off = blocks * 8
self.info.chan2_start = data2_off
for i in xrange(blocks):
for j in xrange(14):
sampsbuf[j] = snddatal[i*14+j]
out_buf = self.repack_adpcm(0, self.deftbl, sampsbuf)
for k in xrange(8):
data[data1_off+k] = out_buf[k]
for j in xrange(14):
sampsbuf[j] = snddatar[i*14+j]
out_buf = self.repack_adpcm(1, self.deftbl, sampsbuf)
for k in xrange(8):
data[data2_off+k] = out_buf[k]
data1_off += 8
data2_off += 8
self.info.loop_end = blocks * 7
return data
def create_bns(self, inbuf, samplerate=44100, channels=2):
self.info.chan_cnt = channels
self.info.samplerate = samplerate
assert samplerate >=32000
self.data.data = ''.join(Struct.int8(p) for p in self.encode(inbuf))
self.data.size = len(self.data.data)
self.header.data_len = self.data.size
self.header.filesize = self.info.size + self.data.size + 8 + self.header.size
self.info.loop_end = self.data.size - (self.data.size / 7)
for x in xrange(16):
self.info.coefficients1[x] = self.deftbl[x]
if self.info.chan_cnt == 2:
for x in xrange(16): self.info.coefficients2[x] = self.deftbl[x]
return
def decode_adpcm(self, index, coefs, buffer):
outbuf = [0 for i in range(14)]
header = Struct.uint8(buffer[0:1], endian='>')
coef_index = (header >> 4) & 0x7
scale = 1 << (header & 0xf)
hist1 = self.phist1[index]
hist2 = self.phist2[index]
coef1 = coefs[coef_index * 2 + 0]
coef2 = coefs[coef_index * 2 + 1]
for x in xrange(14):
sample_byte = Struct.uint8(buffer[x/2+1:x/2+2], endian='>')
if x&1:
nibble = (sample_byte & 0xf0) >> 4
else:
nibble = (sample_byte & 0x0f) >> 0
if nibble >= 8:
nibble -= 16
sample_delta_11 = (scale * nibble) << 11
predicted_sample_11 = coef1*hist1 + coef2*hist2
sample_11 = predicted_sample_11 + sample_delta_11
sample_raw = (sample_11 + 1024) >> 11
sample_raw = clamp(sample_raw, -32768, 32767)
outbuf[x] = sample_raw
hist2 = hist1
hist1 = outbuf[x]
self.phist1[index] = hist1
self.phist2[index] = hist2
return outbuf
def decode(self, buffer, offset):
decoded_buffer = []
if self.info.chan_cnt == 2:
multi = 16
coeff0 = self.info.coefficients1
coeff1 = self.info.coefficients2
elif self.info.chan_cnt == 1:
multi = 8
coeff0 = self.info.coefficients1
coeff1 = self.info.coefficients1
blocks = self.data.size / multi
data1_offset = offset
data2_offset = offset + blocks * 8
decoded_buffer_l = [0 for i in range(blocks * 14)]
decoded_buffer_r = [0 for i in range(blocks * 14)]
for x in xrange(blocks):
out_buffer = self.decode_adpcm(0, coeff0, buffer[data1_offset:data1_offset+8])
for y in xrange(14):
decoded_buffer_l[x*14+y] = out_buffer[y]
out_buffer = self.decode_adpcm(1, coeff1, buffer[data2_offset:data2_offset+8])
for y in xrange(14):
decoded_buffer_r[x*14+y] = out_buffer[y]
data1_offset += 8
data2_offset += 8
for x in xrange(blocks * 14):
decoded_buffer.append(decoded_buffer_l[x])
decoded_buffer.append(decoded_buffer_r[x])
return decoded_buffer
def eat(self, buffer, offset, decode=False):
co = self.header.eat(buffer, offset)
co = self.info.eat(buffer, co)
co = self.data.eat(buffer, co)
self.data.data = buffer[co:]
if decode == True:
buffer_out = self.decode(buffer, co)
return buffer_out
return
def show(self):
self.header.show()
self.info.show()
self.data.show()
return
def write(self, filename):
file = open(filename, 'wb')
if file:
self.header.write(file)
self.info.write(file)
self.data.write(file)
file.close()
else:
print "Could not open file for writing"
return
def main():
if sys.argv[1] == "-d":
file = open(sys.argv[2], 'rb')
if file:
buffer = file.read()
file.close()
else:
print "Could not open file"
sys.exit(2)
bns = BNS()
wavbuffer = bns.eat(buffer, 0x00, True)
wavstring = ''.join(Struct.int16(p) for p in wavbuffer)
f = SoundFile(wavstring, sys.argv[3], bns.info.samplerate)
f.write()
elif sys.argv[1] == "-e":
f = wave.open(sys.argv[2], 'rb')
num_chans = f.getnchannels()
samplerate = f.getframerate()
assert samplerate >= 32000
assert samplerate <= 48000
buffer = f.readframes(f.getnframes())
f.close()
bns = BNS()
bns.create_bns(buffer, samplerate, num_chans)
bns.write(sys.argv[3])
elif sys.argv[1] == "-s":
file = open(sys.argv[2], 'rb')
if file:
buffer = file.read()
file.close()
else:
print "Could not open file"
sys.exit(2)
bns = BNS()
bns.eat(buffer, 0x00, False)
bns.show()
else:
print "Unknown second argument. possiblities are -d and -e"
print "Usage: python bns.py -d <sound.bin> <output.wav>"
print " == OR == "
print " python bns.py -e <input.wav> <sound.bin> "
print " == OR == "
print " python bns.py -s <sound.bin> "
sys.exit(1)
if __name__ == "__main__":
# Import Psyco if available
try:
import psyco
psyco.full()
except ImportError:
print "no psycho import"
if len(sys.argv) == 1:
print "Usage: python bns.py -d <sound.bin> <output.wav>"
print " == OR == "
print " python bns.py -e <input.wav> <sound.bin> "
print " == OR == "
print " python bns.py -s <sound.bin> "
sys.exit(1)
main()

137
WiiPy/common.py Normal file
View File

@ -0,0 +1,137 @@
import os, hashlib, struct, subprocess, fnmatch, shutil, urllib, array, time, sys, tempfile, wave
from cStringIO import StringIO
from Crypto.Cipher import AES
from PIL import Image
from Struct import Struct
def align(x, boundary):
if(x % boundary):
x += (x + boundary) - (x % boundary)
return x
def clamp(var, min, max):
if var < min: var = min
if var > max: var = max
return var
def abs(var):
if var < 0:
var = var + (2 * var)
return var
def hexdump(s, sep=" "): # just dumps hex values
return sep.join(map(lambda x: "%02x" % ord(x), s))
def hexdump2(src, length = 16): # dumps to a "hex editor" style output
result = []
for i in xrange(0, len(src), length):
s = src[i:i + length]
if(len(s) % 4 == 0):
mod = 0
else:
mod = 1
hexa = ''
for j in range((len(s) / 4) + mod):
hexa += ' '.join(["%02X" % ord(x) for x in s[j * 4:j * 4 + 4]])
if(j != ((len(s) / 4) + mod) - 1):
hexa += ' '
printable = s.translate(''.join([(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)]))
result.append("0x%04X %-*s %s\n" % (i, (length * 3) + 2, hexa, printable))
return ''.join(result)
class Crypto(object):
"""This is a Cryptographic/hash class used to abstract away things (to make changes easier)"""
align = 64
@classmethod
def decryptData(self, key, iv, data, align = True):
"""Decrypts some data (aligns to 64 bytes, if needed)."""
if((len(data) % self.align) != 0 and align):
return AES.new(key, AES.MODE_CBC, iv).decrypt(data + ("\x00" * (self.align - (len(data) % self.align))))
else:
return AES.new(key, AES.MODE_CBC, iv).decrypt(data)
@classmethod
def encryptData(self, key, iv, data, align = True):
"""Encrypts some data (aligns to 64 bytes, if needed)."""
if((len(data) % self.align) != 0 and align):
return AES.new(key, AES.MODE_CBC, iv).encrypt(data + ("\x00" * (self.align - (len(data) % self.align))))
else:
return AES.new(key, AES.MODE_CBC, iv).encrypt(data)
@classmethod
def decryptContent(self, titlekey, idx, data):
"""Decrypts a Content."""
iv = struct.pack(">H", idx) + "\x00" * 14
return self.decryptData(titlekey, iv, data)
@classmethod
def decryptTitleKey(self, commonkey, tid, enckey):
"""Decrypts a Content."""
iv = struct.pack(">Q", tid) + "\x00" * 8
return self.decryptData(commonkey, iv, enckey, False)
@classmethod
def encryptContent(self, titlekey, idx, data):
"""Encrypts a Content."""
iv = struct.pack(">H", idx) + "\x00" * 14
return self.encryptData(titlekey, iv, data)
@classmethod
def createSHAHash(self, data): #tested WORKING (without padding)
return hashlib.sha1(data).digest()
@classmethod
def createSHAHashHex(self, data):
return hashlib.sha1(data).hexdigest()
@classmethod
def createMD5HashHex(self, data):
return hashlib.md5(data).hexdigest()
@classmethod
def createMD5Hash(self, data):
return hashlib.md5(data).digest()
@classmethod
def validateSHAHash(self, data, hash):
contentHash = hashlib.sha1(data).digest()
return 1
if (contentHash == hash):
return 1
else:
#raise ValueError('Content hash : %s : len %i' % (hexdump(contentHash), len(contentHash)) + 'Expected : %s : len %i' % (hexdump(hash), len(hash)))
return 0
class WiiObject(object):
@classmethod
def load(cls, data, *args, **kwargs):
self = cls()
self._load(data, *args, **kwargs)
return self
@classmethod
def loadFile(cls, filename, *args, **kwargs):
return cls.load(open(filename, "rb").read(), *args, **kwargs)
def dump(self, *args, **kwargs):
return self._dump(*args, **kwargs)
def dumpFile(self, filename, *args, **kwargs):
open(filename, "wb").write(self.dump(*args, **kwargs))
return filename
class WiiArchive(WiiObject):
@classmethod
def loadDir(cls, dirname):
self = cls()
self._loadDir(dirname)
return self
def dumpDir(self, dirname):
if(not os.path.isdir(dirname)):
os.mkdir(dirname)
self._dumpDir(dirname)
return dirname
class WiiHeader(object):
def __init__(self, data):
self.data = data
def addFile(self, filename):
open(filename, "wb").write(self.add())
def removeFile(self, filename):
open(filename, "wb").write(self.remove())
@classmethod
def loadFile(cls, filename, *args, **kwargs):
return cls(open(filename, "rb").read(), *args, **kwargs)

56
WiiPy/compression.py Normal file
View File

@ -0,0 +1,56 @@
from common import *
class LZ77(WiiHeader):
class WiiLZ77: # class by marcan, used under scope of BSD license
TYPE_LZ77 = 1
def __init__(self, file, offset):
self.file = file
self.offset = offset
self.file.seek(self.offset)
hdr = struct.unpack("<I",self.file.read(4))[0]
self.uncompressed_length = hdr>>8
self.compression_type = hdr>>4 & 0xF
if self.compression_type != self.TYPE_LZ77:
raise ValueError("Unsupported compression method %d"%self.compression_type)
def uncompress(self):
dout = ""
self.file.seek(self.offset + 0x4)
while len(dout) < self.uncompressed_length:
flags = struct.unpack("<B",self.file.read(1))[0]
for i in range(8):
if flags & 0x80:
info = struct.unpack(">H",self.file.read(2))[0]
num = 3 + ((info>>12)&0xF)
disp = info & 0xFFF
ptr = len(dout) - (info & 0xFFF) - 1
for i in range(num):
dout += dout[ptr]
ptr+=1
if len(dout) >= self.uncompressed_length:
break
else:
dout += self.file.read(1)
flags <<= 1
if len(dout) >= self.uncompressed_length:
break
self.data = dout
return self.data
def remove(self):
hdr = self.data[:4]
if hdr != "LZ77":
return self.data
file = StringIO.StringIO(self.data)
file.seek(4)
unc = self.WiiLZ77(file, file.tell())
data = unc.uncompress()
return data
def compress(self, fn = ""):
raise NotImplementedError

357
WiiPy/disc.py Normal file
View File

@ -0,0 +1,357 @@
from common import *
from title import *
class WOD: #WiiOpticalDisc
class discHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.discId = Struct.string(1)
self.gameCode = Struct.string(2)
self.region = Struct.string(1)
self.makerCode = Struct.uint8[2]
self.h = Struct.uint8
self.version = Struct.uint8
self.audioStreaming = Struct.uint8
self.streamingBufSize = Struct.uint8
self.unused = Struct.uint8[14]
self.magic = Struct.uint32
self.title = Struct.string(64)
self.hashVerify = Struct.uint8
self.h3verify = Struct.uint8
def __str__(self):
ret = ''
ret += '%s [%s%s%s]\n' % (self.title, self.discId, self.gameCode, self.region)
if self.region == 'P':
ret += 'Region : PAL\n'
elif self.region == 'E':
ret += 'Region : NTSC\n'
elif self.region == 'J':
ret += 'Region : JPN\n'
ret += 'Version 0x%x Maker %i%i Audio streaming %x\n' % (self.version, self.makerCode[0], self.makerCode[1], self.audioStreaming)
ret += 'Hash verify flag 0x%x H3 verify flag : 0x%x\n' % (self.hashVerify, self.h3verify)
return ret
# Many many thanks to Wiipower
class Apploader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.buildDate = Struct.string(16)
self.entryPoint = Struct.uint32
self.size = Struct.uint32
self.trailingSize = Struct.uint32
self.padding = Struct.uint8[4]
def __str__(self):
ret = ''
ret += 'Apploader built on %s\n' % self.buildDate
ret += 'Entry point 0x%x\n' % self.entryPoint
ret += 'Size %i (%i of them are trailing)\n' % (self.size, self.trailingSize)
return ret
def __str__(self):
ret = ''
ret += '%s\n' % self.discHdr
ret += 'Found %i partitions (table at 0x%x)\n' % (self.partitionCount, self.partsTableOffset)
ret += 'Found %i channels (table at 0x%x)\n' % (self.channelsCount, self.chansTableOffset)
ret += '\n'
ret += 'Partition %i opened (type 0x%x) at 0x%x\n' % (self.partitionOpen, self.partitionType, self.partitionOffset)
ret += 'Partition name : %s' % self.partitionHdr
ret += 'Partition key : %s\n' % hexdump(self.partitionKey)
ret += 'Partition IOS : IOS%i\n' % self.partitionIos
ret += 'Partition tmd : 0x%x (%x)\n' % (self.tmdOffset, self.tmdSize)
ret += 'Partition main.dol : 0x%x (%x)\n' % (self.dolOffset, self.dolSize)
ret += 'Partition FST : 0x%x (%x)\n' % (self.fstSize, self.fstOffset)
ret += '%s\n' % (self.appLdr)
return ret
def __init__(self, f):
self.f = f
self.fp = open(f, 'rb')
self.discHdr = self.discHeader().unpack(self.fp.read(0x400))
if self.discHdr.magic != 0x5D1C9EA3:
raise Exception('Wrong disc magic')
self.fp.seek(0x40000)
self.partitionCount = 1 + struct.unpack(">I", self.fp.read(4))[0]
self.partsTableOffset = struct.unpack(">I", self.fp.read(4))[0] << 2
self.channelsCount = struct.unpack(">I", self.fp.read(4))[0]
self.chansTableOffset = struct.unpack(">I", self.fp.read(4))[0] << 2
self.markedBlocks = []
self.partitionOpen = -1
self.partitionOffset = -1
self.partitionType = -1
def markContent(self, offset, size):
blockStart = offset / 0x7C00
blockLen = (align(size, 0x7C00)) / 0x7C00
for x in range(blockStart, blockStart + blockLen):
try:
self.markedBlocks.index(blockStart + x)
except:
self.markedBlocks.append(blockStart + x)
def decryptBlock(self, block):
if len(block) != 0x8000:
raise Exception('Block size too big/small')
blockIV = block[0x3d0:0x3e0]
#print 'IV %s (len %i)\n' % (hexdump(blockIV), len(blockIV))
blockData = block[0x0400:0x8000]
return Crypto().decryptData(self.partitionKey, blockIV, blockData, True)
def readBlock(self, blockNumber):
self.fp.seek(self.partitionOffset + 0x20000 + (0x8000 * blockNumber))
return self.decryptBlock(self.fp.read(0x8000))
def readPartition(self, offset, size):
readStart = offset / 0x7C00
readLen = (align(size, 0x7C00)) / 0x7C00
blob = ''
#print 'Read at 0x%x (Start on %i block, ends at %i block) for %i bytes' % (offset, readStart, readStart + readLen, size)
self.fp.seek(self.partitionOffset + 0x20000 + (0x8000 * readStart))
for x in range(readLen + 1):
blob += self.decryptBlock(self.fp.read(0x8000))
self.markContent(offset, size)
#print 'Read from 0x%x to 0x%x' % (offset, offset + size)
offset -= readStart * 0x7C00
return blob[offset:offset + size]
def readUnencrypted(self, offset, size):
if offset + size > 0x20000:
raise Exception('This read is on encrypted data')
# FIXMII : Needs testing, extracting the tmd cause to have 10 null bytes in the end instead of 10 useful bytes at start :|
self.fp.seek(self.partitionOffset + 0x2A4 + offset)
return self.fp.read(size)
class fstObject(object):
#TODO: add ability to extract file by path
def __init__(self, name, iso=None):
''' do init stuff here '''
self.parent = None
self.type = 1 #directory: 1, file:0
self.name = name
self.nameOff = 0
self.fileOffset = 0
self.size = 0
self.children = []
self.iso = iso
def addChild(self, child):
if self.type == 0:
raise Exception('I am not a directory.')
child.parent = self
self.children.append(child)
def getISO(self):
if(self.parent == None):
return self.iso
return self.parent.getISO()
def getList(self, pad=0):
if self.type == 0:
return ("\t" * pad) + self.getPath() + "\n"
str = "%s[%s]\n" % ("\t" * (pad), self.getPath())
for child in self.children:
str += child.getList(pad+1)
return str
def count(self):
if self.type == 0:
return 1
i = 0
for child in self.children:
i += child.count()
return i
def getPath(self):
if(self.parent == None):
return "/"
if(self.type == 1):
return self.parent.getPath() + self.name + "/"
return self.parent.getPath() + self.name
def write(self, cwd):
if(self.type==0):
print cwd + self.getPath()
#print self.nameOff
open(cwd + self.getPath(), 'w+b').write(self.getISO().readPartition(self.fileOffset, self.size))
if(self.type==1):
if(self.parent != None):
try:
os.makedirs(cwd + self.getPath())
except:
j = None
for child in self.children:
child.write(cwd)
def parseFst(self, fst, names, i, fstDir):
size = struct.unpack(">I", fst[(12*i + 8):(12*i + 8) + 4])[0]
nameOff = struct.unpack(">I", fst[(12*i):(12*i) + 4])[0] & 0x00ffffff
fileName = names[nameOff:]
fileName = fileName[:fileName.find('\0')]
if i == 0:
j = 1
while(j<size):
j = self.parseFst(fst, names, j, fstDir)
return size
if fst[12 * i] == '\x01':
newDir = self.fstObject(fileName)
j = i+1
while(j<size):
j = self.parseFst(fst, names, j, newDir)
fstDir.addChild(newDir)
return size
else:
fileOffset = 4 * struct.unpack(">I", fst[(12*i + 4):(12*i + 4) + 4])[0]
newFile = self.fstObject(fileName)
newFile.type = 0
newFile.fileOffset = fileOffset
newFile.size = size
newFile.nameOff = nameOff
fstDir.addChild(newFile)
self.markContent(fileOffset, size)
return i+1
def openPartition(self, index):
if index+1 > self.partitionCount:
raise ValueError('Partition index too big')
self.partitionOpen = index
self.partitionOffset = self.partsTableOffset + (8 * self.partitionOpen)
self.fp.seek(self.partsTableOffset + (8 * self.partitionOpen))
self.partitionOffset = struct.unpack(">I", self.fp.read(4))[0] << 2
self.partitionType = struct.unpack(">I", self.fp.read(4))[0]
self.fp.seek(self.partitionOffset)
self.tikData = self.fp.read(0x2A4)
self.partitionKey = Ticket(self.tikData).getTitleKey()
self.tmdSize = struct.unpack(">I", self.fp.read(4))[0]
self.tmdOffset = struct.unpack(">I", self.fp.read(4))[0] >> 2
self.certsSize = struct.unpack(">I", self.fp.read(4))[0]
self.certsOffset = struct.unpack(">I", self.fp.read(4))[0] >> 2
self.H3TableOffset = struct.unpack(">I", self.fp.read(4))[0] >> 2
self.dataOffset = struct.unpack(">I", self.fp.read(4))[0] >> 2
self.dataSize = struct.unpack(">I", self.fp.read(4))[0] >> 2
self.fstOffset = 4 * struct.unpack(">I", self.readPartition (0x424, 4))[0]
self.fstSize = 4 * struct.unpack(">I", self.readPartition (0x428, 4))[0]
self.dolOffset = 4 * struct.unpack(">I", self.readPartition (0x420, 4))[0]
self.dolSize = self.fstOffset - self.dolOffset
self.appLdr = self.Apploader().unpack(self.readPartition (0x2440, 32))
self.partitionHdr = self.discHeader().unpack(self.readPartition (0x0, 0x400))
self.partitionIos = TMD(self.getPartitionTmd()).getIOSVersion() & 0x0fffffff
def getFst(self):
fstBuf = self.readPartition(self.fstOffset, self.fstSize)
return fstBuf
def getIsoBootmode(self):
if self.discHdr.discId == 'R' or self.discHdr.discId == '_':
return 2
elif self.discHdr.discId == '0':
return 1
def getOpenedPartition(self):
return self.partitionOpen
def getOpenedPartitionOffset(self):
return self.partitionOffset
def getOpenedPartitionType(self):
return self.partitionType
def getPartitionsCount(self):
return self.partitionCount
def getChannelsCount(self):
return self.channelsCount
def getPartitionCerts(self):
return self.readUnencrypted(self.certsOffset, self.certsSize)
def getPartitionH3Table(self):
return self.readUnencrypted(self.H3TableOffset, 0x18000)
def getPartitionTmd(self):
return self.readUnencrypted(self.tmdOffset, self.tmdSize)
def getPartitionTik(self):
self.fp.seek(self.partitionOffset)
return self.fp.read(0x2A4)
def getPartitionApploader(self):
return self.readPartition (0x2440, self.appLdr.size + self.appLdr.trailingSize + 32)
def getPartitionMainDol(self):
return self.readPartition (self.dolOffset, self.dolSize)
def dumpPartition(self, fn):
rawPartition = open(fn, 'w+b')
print 'Partition useful data %i Mb' % (align(len(self.markedBlocks) * 0x7C00, 1024) / 1024 / 1024)
self.fp.seek(self.partitionOffset)
rawPartition.write(self.fp.read(0x2A4)) # Write teh TIK
rawPartition.write(self.readUnencrypted(0, 0x20000 - 0x2A4)) # Write the TMD and other stuff
for x in range(len(self.markedBlocks)):
rawPartition.write(self.readBlock(self.markedBlocks[x])) # Write each decrypted block
class updateInf():
def __init__(self, f):
self.buffer = open(f, 'r+b').read()
def __str__(self):
out = ''
self.buildDate = self.buffer[:0x10]
self.fileCount = struct.unpack('>L', self.buffer[0x10:0x14])[0]
out += 'This update partition was built on %s and has %i files\n\n' % (self.buildDate, self.fileCount)
for x in range(self.fileCount):
updateEntry = self.buffer[0x20 + x * 0x200:0x20 + (x + 1) * 0x200]
titleType = struct.unpack('>L', updateEntry[:0x4])[0]
titleAttr = struct.unpack('>L', updateEntry[0x4:0x8])[0]
titleUnk1 = struct.unpack('>L', updateEntry[0x8:0xC])[0]
titleType2 = struct.unpack('>L', updateEntry[0xC:0x10])[0]
titleFile = updateEntry[0x10:0x50]
titleFile = titleFile[:titleFile.find('\x00')]
titleID = struct.unpack('>Q', updateEntry[0x50:0x58])[0]
titleMajor = struct.unpack('>B', updateEntry[0x58:0x59])[0]
titleMinor = struct.unpack('>B', updateEntry[0x59:0x5A])[0]
titleName = updateEntry[0x60:0xA0]
titleName = titleName[:titleName.find('\x00')]
titleInfo = updateEntry[0xA0:0xE0]
titleInfo = titleInfo[:titleInfo.find('\x00')]
out += 'Update type : 0x%x\n' % titleType
out += 'Update flag : %i (0 means critical, 1 means need reboot)\n' % titleAttr
out += 'Update file : %s\n' % titleFile
out += 'Update ID : %lu\n' % titleID
out += 'Update version : %i.%i\n' % (titleMajor, titleMinor)
out += 'Update name : %s\n' % titleName
out += 'Update info : %s\n' % titleInfo
out += '\n'
return out

View File

257
WiiPy/experimental/bmg.py Executable file
View File

@ -0,0 +1,257 @@
#!/usr/bin/python
import sys, re, struct
from Struct import Struct
def nullterm(str_plus):
z = str_plus.find('\x00\x00')
if z != -1:
return str_plus[:z]
else:
return str_plus
def denullterm(str_plus):
z = str_plus.find('\r\n')
if z != -1:
return str_plus[:z]
else:
return str_plus
class BMG(object):
class BMG_DAT1(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.length = Struct.uint32
def __str__(self):
return_string = "Magic: %s\n" % self.magic
return_string += "Length: %08x\n " % self.length
return return_string
def write(self, file):
file.write(self.magic)
file.write(struct.pack('>I', self.length))
return
class BMG_INF1(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.length = Struct.uint32
self.count = Struct.uint16
self.unknown01 = Struct.uint16
def __str__(self):
return_string = "Magic: %s\n" % self.magic
return_string += "Length: %08x\n " % self.length
return_string += "Count: %04x\n" % self.count
return_string += "Unknown: %04x\n" % self.unknown01
return return_string
def write(self, file):
file.write(self.magic)
file.write(struct.pack('>I', self.length))
file.write(struct.pack('>H', self.count))
file.write(struct.pack('>H', self.unknown01))
return
class BMG_Header(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.magic2 = Struct.string(4)
self.length = Struct.uint32
self.chunk_cnt = Struct.uint32
self.unknown01 = Struct.uint8
self.unknown02 = Struct.uint8
self.unknown03 = Struct.uint16
self.unknown04 = Struct.uint32
self.unknown05 = Struct.uint32
self.unknown06 = Struct.uint32
def __str__(self):
return_string = "Magic: %s\n" % self.magic
return_string += "Magic: %s\n" % self.magic2
return_string += "Length: %08x\n" % self.length
return_string += "Chunk Count: %08x\n" % self.chunk_cnt
return_string += "Unknown01: %02x\n" % self.unknown01
return_string += "Unknown02: %02x\n" % self.unknown02
return_string += "Unknown03: %04x\n" % self.unknown03
return_string += "Unknown04: %08x\n" % self.unknown04
return_string += "Unknown05: %08x\n" % self.unknown05
return_string += "Unknown06: %08x\n" % self.unknown06
return return_string
def write(self, file):
file.write(self.magic)
file.write(self.magic2)
file.write(struct.pack('>I', self.length))
file.write(struct.pack('>I', self.chunk_cnt))
file.write(struct.pack('>B', self.unknown01))
file.write(struct.pack('>B', self.unknown02))
file.write(struct.pack('>H', self.unknown03))
file.write(struct.pack('>I', self.unknown04))
file.write(struct.pack('>I', self.unknown05))
file.write(struct.pack('>I', self.unknown06))
return
def __init__(self, data=None, out_file=None, debug=False):
self.data = []
if data != None:
self.Unpack(data, out_file, debug)
def Unpack(self, data, out_file, debug):
file = open(out_file, 'wb')
if file:
pos = 0
header = self.BMG_Header()
header.unpack(data[pos:pos+len(header)])
pos += len(header)
if debug == True:
print header
print "\n%08x\n" % pos
info = self.BMG_INF1()
info.unpack(data[pos:pos+len(info)])
pos += len(info)
if debug == True:
print info
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
if debug == True:
print "Unknown: %08x" % unknown
print "\n%08x\n" % pos
offset_list = []
for x in xrange(info.count):
offset = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
if debug == True:
print "Offset: %08x" % offset
offset_list.append(offset)
while pos % 0x10:
padding = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
if debug == True:
print "Padding: %08x" % padding
if debug == True:
print "\n%08x\n" % pos
dat1 = self.BMG_DAT1()
dat1.unpack(data[pos:pos+len(dat1)])
pos += len(dat1)
if debug == True:
print dat1
if debug == True:
print "\n%08x\n" % pos
temp = pos
unknown = Struct.uint16(data[pos:pos+2], endian='>')
pos += 2
if debug == True:
print "Unknown: %04x" % unknown
for x in xrange(info.count):
pos = temp + offset_list[x]
string = nullterm(data[pos:])
string = unicode(string, 'utf_16_be')
file.write(string.encode('utf-8'))
file.write('\r')
file.write('\n')
if debug == True:
print "String: %s" % string.encode('utf-8')
file.close()
else:
print "Could not open file for writing"
sys.exit(1)
def write(self, data, out_file):
file = open(out_file, 'wb')
if file:
pos = 0
count = 0
strings_list = []
while pos < len(data):
temp = denullterm(data[pos:])
pos += len(temp) + 2
string = unicode(temp, 'utf-8')
strings_list.append(string)
count += 1
offsets_list = []
offset = 2
for x in xrange(count):
offsets_list.append(offset)
offset += len(strings_list[x]) * 2 + 2
dat1 = self.BMG_DAT1()
dat1.length = offset + 8 + (0x10 - (offset % 0x10))
dat_pad_to_add = 0x10 - (offset % 0x10)
info = self.BMG_INF1()
info.length = 0x10 + 4 * count + (0x10 - ((4 * count) % 0x10))
info_pad_to_add = 0x10 - ((4*count) % 0x10)
header = self.BMG_Header()
header.magic = "MESG"
header.magic2 = "bmg1"
header.length = info.length + dat1.length + 0x20
header.chunk_cnt = 2
header.unknown01 = 2
header.unknown02 = 0
header.unknown03 = 0
header.unknown04 = 0
header.unknown05 = 0
header.unknown06 = 0
header.write(file)
info.magic = "INF1"
info.count = count
info.unknown01 = 4
info.write(file)
unknown = 0
file.write(struct.pack('>I', unknown))
offset_list = []
for x in offsets_list:
file.write(struct.pack('>I', x))
padding = 0
for x in xrange(info_pad_to_add):
file.write(struct.pack('>B', padding))
dat1.magic = "DAT1"
dat1.write(file)
unknown = 0
file.write(struct.pack('>H', unknown))
for x in strings_list:
file.write(x.encode('utf_16_be'))
file.write('\x00\x00')
file.write("\n")
padding = 0
for x in xrange(dat_pad_to_add):
file.write(struct.pack('>B', padding))
file.close()
else:
print "Could not open file for writing"
sys.exit(1)
def main():
if len(sys.argv) == 1:
print 'Usage: python bmg.py -r <filename.bmg> <filename.hog>'
print ' == OR == '
print 'Usage: python bmg.py -w> <filename.hog> <filename.bmg'
sys.exit(1)
if sys.argv[1] == "-r":
f = open(sys.argv[2], 'rb')
if f:
bmg_buffer = f.read()
f.close()
else:
print 'Could not open file for reading'
sys.exit(1)
bmg = BMG(bmg_buffer, sys.argv[3], debug=False)
elif sys.argv[1] == "-w":
f = open(sys.argv[2], 'rb')
if f:
bmg_buffer = f.read()
f.close()
else:
print "Could not open file for reading"
sys.exit(1)
bmg = BMG()
bmg.write(bmg_buffer, sys.argv[3])
if __name__ == "__main__":
main()

584
WiiPy/experimental/breff.py Executable file
View File

@ -0,0 +1,584 @@
#!/usr/bin/python
import sys, struct
from Struct import Struct
def nullterm(str_plus):
z = str_plus.find('\0')
if z != -1:
return str_plus[:z]
else:
return str_plus
class BREFF(object):
class BREFF_REFF_Section2(Struct):
__endian__ = Struct.BE
def __format__(self):
self.unknown00 = Struct.uint32
self.unknown01 = Struct.uint32
self.unknown02 = Struct.uint32
self.unk03p1 = Struct.uint16
self.unk03p2 = Struct.uint16
self.unk04p1 = Struct.int16
self.unk04p2 = Struct.uint16
self.unknown05 = Struct.uint32
self.unknown06 = Struct.float
self.unknown07 = Struct.float
self.unknown08 = Struct.uint32
self.unknown09 = Struct.uint32
self.unknown10 = Struct.float
self.unknown11 = Struct.float
self.unknown12 = Struct.uint32
self.unknown13 = Struct.float
self.unknown14 = Struct.uint32
self.unknown15 = Struct.uint32
self.unk16p1 = Struct.uint16
self.unk16p2 = Struct.uint16
self.unknown17 = Struct.float
self.unknown18 = Struct.float
self.unknown19 = Struct.uint32
self.unknown20 = Struct.float
self.unknown21 = Struct.float
self.unknown22 = Struct.float
self.unknown23 = Struct.float
self.unknown24 = Struct.float
self.unknown25 = Struct.float
self.unknown26 = Struct.uint32
self.unknown27 = Struct.uint32
self.unknown28 = Struct.uint32
self.unknown29 = Struct.uint32
self.unknown30 = Struct.uint32
self.unknown31 = Struct.float
self.unknown32 = Struct.uint32
self.unknown33 = Struct.uint32
self.unknown34 = Struct.uint32
self.unknown35 = Struct.uint32
self.unknown36 = Struct.uint32
self.unknown37 = Struct.float
self.unknown38 = Struct.float
self.unknown39 = Struct.float
self.unknown40 = Struct.float
self.unknown41 = Struct.float
self.unknown42 = Struct.uint32
self.unknown43 = Struct.uint32
self.unknown44 = Struct.float
self.unknown45 = Struct.uint32
self.unknown46 = Struct.uint32
self.unknown47 = Struct.uint32
self.unknown48 = Struct.uint32
self.unknown49 = Struct.uint32
self.unknown50 = Struct.uint32
self.unknown51 = Struct.uint32
self.unknown52 = Struct.uint32
self.unknown53 = Struct.uint32
self.unknown54 = Struct.uint32
self.unknown55 = Struct.uint32
self.unknown56 = Struct.uint32
self.unknown57 = Struct.uint32
self.unknown58 = Struct.uint32
self.unknown59 = Struct.uint32
self.unknown60 = Struct.uint32
self.unknown61 = Struct.uint32
self.unknown62 = Struct.uint32
self.unknown63 = Struct.uint32
self.unknown64 = Struct.uint32
self.unknown65 = Struct.uint32
self.unknown66 = Struct.uint32
self.unknown67 = Struct.uint32
self.unknown68 = Struct.uint32
self.unknown69 = Struct.uint32
self.unknown70 = Struct.uint32
self.unknown71 = Struct.uint32
self.unknown72 = Struct.uint32
self.unknown73 = Struct.uint32
self.unknown74 = Struct.uint32
self.unknown75 = Struct.uint32
self.unknown76 = Struct.uint32
self.unknown77 = Struct.uint32
self.unknown78 = Struct.uint32
self.unknown79 = Struct.uint32
self.unknown80 = Struct.uint32
self.unknown81 = Struct.float
self.unknown82 = Struct.float
self.unknown83 = Struct.float
self.unknown84 = Struct.float
self.unknown85 = Struct.uint32
self.unknown86 = Struct.uint32
self.unknown87 = Struct.uint32
self.unknown88 = Struct.float
self.unknown89 = Struct.float
self.unknown90 = Struct.float
self.unknown91 = Struct.float
self.unknown92 = Struct.float
self.unknown93 = Struct.float
self.unknown94 = Struct.uint32
self.unknown95 = Struct.uint32
self.unknown96 = Struct.uint32
self.unknown97 = Struct.uint32
self.unknown98 = Struct.uint32
self.unknown99 = Struct.uint32
self.unknownA0 = Struct.uint32
self.unknownA1 = Struct.uint32
self.unknownA2 = Struct.uint32
self.unknownA3 = Struct.uint32
self.unknownA4 = Struct.uint32
self.unknownA5 = Struct.uint32
self.unknownA6 = Struct.uint32
self.unknownA7 = Struct.uint32
self.unknownA8 = Struct.uint32
self.unknownA9 = Struct.uint32
self.unknownB0 = Struct.uint32
self.unknownB1 = Struct.uint32
def __str__(self):
return_string = "Unknown00: %08x\n" % self.unknown00
return_string += "Unknown01: %08x\talways 00000128 ?\n" % self.unknown01
return_string += "Unknown02: %08x\talways 80000xxx ?\n" % self.unknown02
return_string += "Unknown03: %04x\t%04x\n" % (self.unk03p1 , self.unk03p2)
return_string += "Unknown04: %.2d\t%04x\n" % (self.unk04p1 , self.unk04p2)
return_string += "Unknown05: %08x\n" % self.unknown05
return_string += "Unknown06: %.9f\n" % self.unknown06
return_string += "Unknown07: %f\n" % self.unknown07
return_string += "Unknown08: %08x\n" % self.unknown08
return_string += "Unknown09: %08x\n" % self.unknown09
return_string += "Size Outer Radius X: %.9f\n" % self.unknown10
return_string += "Size Outer Radius Y: %.9f\n" % self.unknown11
return_string += "Size Outer Radius Z: %.9f\n" % self.unknown12
return_string += "Inner Radius: %.9f\n" % self.unknown13
return_string += "Unknown14: %08x\n" % self.unknown14
return_string += "Unknown15: %08x\n" % self.unknown15
return_string += "Unknown16: %04x\t%04x\n" % (self.unk16p1, self.unk16p2)
return_string += "All Direction Speed: %.9f\n" % self.unknown17
return_string += "Y Axis Difuse Speed: %.9f\n" % self.unknown18
return_string += "Random Direction Speed: %.9f\n" % self.unknown19
return_string += "Normal Direction Speed: %.9f\n" % self.unknown20
return_string += "Unknown21: %.9f\n" % self.unknown21
return_string += "Move to Specific Direction: %.9f\n" % self.unknown22
return_string += "Unknown23: %08x\n" % self.unknown23
return_string += "Unknown24: %.20f\n" % self.unknown24
return_string += "Unknown25: %.9f\n" % self.unknown25
return_string += "Unknown26: %08x\n" % self.unknown26
return_string += "Unknown27: %.9f\n" % self.unknown27
return_string += "Unknown28: %.9f\n" % self.unknown28
return_string += "Unknown29: %.9f\n" % self.unknown29
return_string += "Unknown30: %08x\n" % self.unknown30
return_string += "Unknown31: %.9f\n" % self.unknown31
return_string += "Unknown32: %08x\n" % self.unknown32
return_string += "Four Bytes: %08x\n" % self.unknown33
return_string += "Unknown34: %08x\n" % self.unknown34
return_string += "Unknown35: %08x\n" % self.unknown35
return_string += "Unknown36: %08x\n" % self.unknown36
return_string += "Transform Scale X: %.9f\n" % self.unknown37
return_string += "Transform Scale Y: %.9f\n" % self.unknown38
return_string += "Transform Scale Z: %.9f\n" % self.unknown39
return_string += "Center of Particle SRT Horiz: %.9f\n" % self.unknown40
return_string += "Center of Particle SRT Vert: %.9f\n" % self.unknown41
return_string += "Unknown42: %08x\n" % self.unknown42
return_string += "Unknown43: %08x\n" % self.unknown43
return_string += "Unknown44: %.9f\n" % self.unknown44
return_string += "Unknown45: %08x\n" % self.unknown45
return_string += "Unknown46: %08x\n" % self.unknown46
return_string += "Unknown47: %08x\n" % self.unknown47
return_string += "Unknown48: %08x\n" % self.unknown48
return_string += "Unknown49: %08x\n" % self.unknown49
return_string += "Unknown50: %08x\n" % self.unknown50
return_string += "Unknown51: %08x\n" % self.unknown51
return_string += "Unknown52: %08x\n" % self.unknown52
return_string += "Unknown53: %08x\n" % self.unknown53
return_string += "Unknown54: %08x\n" % self.unknown54
return_string += "Unknown55: %08x\n" % self.unknown55
return_string += "Unknown56: %08x\n" % self.unknown56
return_string += "Unknown57: %08x\n" % self.unknown57
return_string += "Unknown58: %08x\n" % self.unknown58
return_string += "Unknown59: %08x\n" % self.unknown59
return_string += "Unknown60: %08x\n" % self.unknown60
return_string += "Unknown61: %08x\n" % self.unknown61
return_string += "Unknown62: %08x\n" % self.unknown62
return_string += "Unknown63: %08x\n" % self.unknown63
return_string += "Unknown64: %08x\n" % self.unknown64
return_string += "Unknown65: %08x\n" % self.unknown65
return_string += "Unknown66: %08x\n" % self.unknown66
return_string += "Unknown67: %08x\n" % self.unknown67
return_string += "Unknown68: %08x\n" % self.unknown68
return_string += "Unknown69: %08x\n" % self.unknown69
return_string += "Unknown70: %08x\n" % self.unknown70
return_string += "Unknown71: %08x\n" % self.unknown71
return_string += "Unknown72: %08x\n" % self.unknown72
return_string += "Unknown73: %08x\n" % self.unknown73
return_string += "Unknown74: %08x\n" % self.unknown74
return_string += "Unknown75: %08x\n" % self.unknown75
return_string += "Unknown76: %08x\n" % self.unknown76
return_string += "Unknown77: %08x\n" % self.unknown77
return_string += "Unknown78: %08x\n" % self.unknown78
return_string += "Unknown79: %08x\n" % self.unknown79
return_string += "Unknown80: %08x\n" % self.unknown80
return_string += "Unknown81: %.9f\n" % self.unknown81
return_string += "Unknown82: %.9f\n" % self.unknown82
return_string += "Unknown83: %.9f\n" % self.unknown83
return_string += "Unknown84: %.9f\n" % self.unknown84
return_string += "Unknown85: %08x\n" % self.unknown85
return_string += "Unknown86: %08x\n" % self.unknown86
return_string += "Unknown87: %08x\n" % self.unknown87
return_string += "Unknown88: %.9f\n" % self.unknown88
return_string += "Unknown89: %.9f\n" % self.unknown89
return_string += "Unknown90: %.9f\n" % self.unknown90
return_string += "Unknown91: %.9f\n" % self.unknown91
return_string += "Unknown92: %.9f\n" % self.unknown92
return_string += "Unknown93: %.9f\n" % self.unknown93
return_string += "Unknown94: %08x\n" % self.unknown94
return_string += "Unknown95: %08x\n" % self.unknown95
return_string += "Unknown96: %08x\n" % self.unknown96
return_string += "Unknown97: %08x\n" % self.unknown97
return_string += "Unknown98: %08x\n" % self.unknown98
return_string += "Unknown99: %08x\n" % self.unknown99
return_string += "UnknownA0: %08x\n" % self.unknownA0
return_string += "UnknownA1: %08x\n" % self.unknownA1
return_string += "UnknownA2: %08x\n" % self.unknownA2
return_string += "UnknownA3: %08x\n" % self.unknownA3
return_string += "UnknownA4: %08x\n" % self.unknownA4
return_string += "UnknownA5: %08x\n" % self.unknownA5
return_string += "UnknownA6: %08x\n" % self.unknownA6
return_string += "UnknownA7: %08x\n" % self.unknownA7
return_string += "UnknownA8: %08x\n" % self.unknownA8
return_string += "UnknownA9: %08x\n" % self.unknownA9
return_string += "UnknownB0: %08x\n" % self.unknownB0
return_string += "UnknownB1: %08x\n" % self.unknownB1
return return_string
class BREFF_REFF_StringSection1(Struct):
__endian__ = Struct.BE
def __format__(self):
self.offset = Struct.uint32
self.length = Struct.uint32
def __str__(self):
return_string = "Offset: %08x\n" % self.offset
return_string += "Length: %08x\n" % self.length
return return_string
class BREFF_REFF_StringHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.offset = Struct.uint16
self.length = Struct.uint16
self.string_cnt = Struct.uint16
self.unknown01 = Struct.uint16
def __str__(self):
return_string = "Offset: %04x\n" % self.offset
return_string += "Offset: %04x\n" % self.length
return_string += "String Count: %04x\n" % self.string_cnt
return_string += "Unknown01: %04x" % self.unknown01
return return_string
class BREFF_REFF_Project(Struct):
__endian__ = Struct.BE
def __format__(self):
self.length = Struct.uint32
self.unknown01 = Struct.uint32
self.unknown02 = Struct.uint32
self.str_length = Struct.uint16
self.unknown03 = Struct.uint16
def __str__(self):
return_string = "Length: %08x\n" % self.length
return_string += "Unknown01: %08x\n" % self.unknown01
return_string += "Unknown02: %08x\n" % self.unknown02
return_string += "Number of Strings: %04x\n" % self.str_length
return_string += "Unknown: %04x" % self.unknown03
return return_string
class BREFF_REFF(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.length = Struct.uint32
def __str__(self):
return_string = "Magic: %s\n" % self.magic
return_string += "Length: %08x\n" % self.length
return return_string
class BREFF_Header(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.version = Struct.uint32
self.length = Struct.uint32
self.header_size = Struct.uint16
self.chunk_cnt = Struct.uint16
def __str__(self):
return_string = "Magic: %s\n" % self.magic
return_string += "Version: %08x\n" % self.version
return_string += "Length: %08x\n" % self.length
return_string += "Header Size: %04x\n" % self.header_size
return_string += "Chunk Count: %04x\n" % self.chunk_cnt
return return_string
def __init__(self, data):
self.data = []
if data != None:
self.Unpack(data)
def Unpack(self, data):
pos = 0
header = self.BREFF_Header()
header.unpack(data[pos:pos+len(header)])
pos += len(header)
print header
assert header.magic == "REFF"
assert header.version == 0xfeff0004
reff = self.BREFF_REFF()
reff.unpack(data[pos:pos+len(reff)])
pos += len(reff)
print reff
assert reff.magic == "REFF"
reff_project = self.BREFF_REFF_Project()
reff_project.unpack(data[pos:pos+len(reff_project)])
pos += len(reft_project)
print reff_project
string = nullterm(data[pos:pos+reff_project.str_length])
pos += reff_project.str_length
print "String: %s\n" % string
while pos %2:
unknown = Struct.uint8(data[pos:pos+1])
pos += 1
print "Padding: %02x" % unknown
print "\n%08x\n" % pos
temp = pos
reff_string_header = self.BREFF_REFF_StringHeader()
reff_string_header.unpack(data[pos:pos+len(reff_string_header)])
pos += len(reff_string_header)
print reff_string_header
print "\n%08x\n" % pos
string_groups = []
for x in xrange(reff_string_header.string_cnt):
str_length = Struct.uint16(data[pos:pos+2], endian='>')
pos += 2
print "String Length with null added: %04x" % str_length
string = nullterm(data[pos:pos+str_length])
pos += str_length
print "String: %s" % string
string_section1 = self.BREFF_REFF_StringSection1()
string_section1.unpack(data[pos:pos+len(string_section1)])
pos += len(string_section1)
print string_section1
string_groups.append(string_section1)
print "\n%08x\n" % pos
while pos % 0x04:
padding = Struct.uint8(data[pos:pos+1])
pos += 1
print "Padding: %02x" % padding
print "\n%08x\n" % pos
assert pos == string_groups[0].offset + temp
for x in xrange(reff_string_header.string_cnt):
pos = temp + string_groups[x].offset
reff_section2 = self.BREFF_REFF_Section2()
reff_section2.unpack(data[pos:pos+len(reff_section2)])
pos += len(reff_section2)
print reff_section2
print "\n%08x\n" % pos
''' LARGE TEST DATA
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown01: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown02: %08x" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown03: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown04: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown05: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown06: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown07: %f" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown08: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown09: %08x" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Size Outer Radius X: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Size Outer Radius Y: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Size Outer Radius Z: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Inner Radius: %f" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown14: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown15: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown16: %08x" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "All Direction Speed: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Y Axis Difuse Speed: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Random Direction Speed: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Normal Direction Speed: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "PI DIVIDED BY 4 BITCHES: %.20f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Move to specific direction: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown23: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "PI BITCHES: %.20f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "PI DIVIDED BY 2 BITCHES: %.20f" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown26: %08x" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown27: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown28: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown29: %f" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown30: %08x" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown31: %f" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown32: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Bytes: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown34: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown35: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown36: %08x" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Transform Scale X: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Transform Scale Y: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Transform Scale Z: %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Center of Particle SRT Horizontal(x): %f" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Center of Particle SRT Verticle(y): %f" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown42: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown43: %08x" % unknown
unknown = Struct.float(data[pos:pos+4], endian='>')
pos += 4
print "Unknown44: %.20f" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown45: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown46: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown47: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown48: %08x" % unknown
LARGE TEST DATA '''
''' BEGIN TEST DATA
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
END TEST DATA '''
def main():
if len(sys.argv) != 2:
print 'Usage: python breff.py <filename>'
sys.exit(1)
f = open(sys.argv[1], 'rb')
if f:
reff = f.read()
f.close()
assert reff[0:8] == 'REFF\xfe\xff\x00\x04'
breff = BREFF(reff)
else:
print 'Could not open %s' % sys.argv[1]
sys.exit(1)
if __name__ == "__main__":
main()

467
WiiPy/experimental/breft.py Executable file
View File

@ -0,0 +1,467 @@
#!/usr/bin/python
import sys, struct
from Struct import Struct
def nullterm(str_plus):
z = str_plus.find('\0')
if z != -1:
return str_plus[:z]
else:
return str_plus
class BREFT(object):
class BREFT_REFT_Section2(Struct):
__endian__ = Struct.BE
def __format__(self):
self.unknown00 = Struct.uint32
self.unknown01 = Struct.uint32
self.unknown02 = Struct.uint32
self.unknown03 = Struct.uint32
self.unknown04 = Struct.uint32
self.unknown05 = Struct.uint32
self.unknown06 = Struct.uint32
self.unknown07 = Struct.uint32
self.unknown08 = Struct.uint32
self.unknown09 = Struct.uint32
self.unknown10 = Struct.uint32
self.unknown11 = Struct.uint32
self.unknown12 = Struct.uint32
self.unknown13 = Struct.uint32
self.unknown14 = Struct.uint32
self.unknown15 = Struct.uint32
self.unknown16 = Struct.uint32
self.unknown17 = Struct.uint32
self.unknown18 = Struct.uint32
self.unknown19 = Struct.uint32
self.unknown20 = Struct.uint32
self.unknown21 = Struct.uint32
self.unknown22 = Struct.uint32
self.unknown23 = Struct.uint32
self.unknown24 = Struct.uint32
self.unknown25 = Struct.uint32
self.unknown26 = Struct.uint32
self.unknown27 = Struct.uint32
self.unknown28 = Struct.uint32
self.unknown29 = Struct.uint32
self.unknown30 = Struct.uint32
self.unknown31 = Struct.uint32
self.unknown32 = Struct.uint32
self.unknown33 = Struct.uint32
self.unknown34 = Struct.uint32
self.unknown35 = Struct.uint32
self.unknown36 = Struct.uint32
self.unknown37 = Struct.uint32
self.unknown38 = Struct.uint32
self.unknown39 = Struct.uint32
self.unknown40 = Struct.uint32
self.unknown41 = Struct.uint32
self.unknown42 = Struct.uint32
self.unknown43 = Struct.uint32
self.unknown44 = Struct.uint32
self.unknown45 = Struct.uint32
self.unknown46 = Struct.uint32
self.unknown47 = Struct.uint32
self.unknown48 = Struct.uint32
self.unknown49 = Struct.uint32
self.unknown50 = Struct.uint32
self.unknown51 = Struct.uint32
self.unknown52 = Struct.uint32
self.unknown53 = Struct.uint32
self.unknown54 = Struct.uint32
self.unknown55 = Struct.uint32
self.unknown56 = Struct.uint32
self.unknown57 = Struct.uint32
self.unknown58 = Struct.uint32
self.unknown59 = Struct.uint32
self.unknown60 = Struct.uint32
self.unknown61 = Struct.uint32
self.unknown62 = Struct.uint32
self.unknown63 = Struct.uint32
self.unknown64 = Struct.uint32
self.unknown65 = Struct.uint32
self.unknown66 = Struct.uint32
self.unknown67 = Struct.uint32
self.unknown68 = Struct.uint32
self.unknown69 = Struct.uint32
self.unknown70 = Struct.uint32
self.unknown71 = Struct.uint32
self.unknown72 = Struct.uint32
self.unknown73 = Struct.uint32
self.unknown74 = Struct.uint32
self.unknown75 = Struct.uint32
self.unknown76 = Struct.uint32
self.unknown77 = Struct.uint32
self.unknown78 = Struct.uint32
self.unknown79 = Struct.uint32
self.unknown80 = Struct.uint32
self.unknown81 = Struct.uint32
self.unknown82 = Struct.uint32
self.unknown83 = Struct.uint32
self.unknown84 = Struct.uint32
self.unknown85 = Struct.uint32
self.unknown86 = Struct.uint32
self.unknown87 = Struct.uint32
self.unknown88 = Struct.uint32
self.unknown89 = Struct.uint32
self.unknown90 = Struct.uint32
self.unknown91 = Struct.uint32
self.unknown92 = Struct.uint32
self.unknown93 = Struct.uint32
self.unknown94 = Struct.uint32
self.unknown95 = Struct.uint32
self.unknown96 = Struct.uint32
self.unknown97 = Struct.uint32
self.unknown98 = Struct.uint32
self.unknown99 = Struct.uint32
self.unknownA0 = Struct.uint32
self.unknownA1 = Struct.uint32
self.unknownA2 = Struct.uint32
self.unknownA3 = Struct.uint32
self.unknownA4 = Struct.uint32
self.unknownA5 = Struct.uint32
self.unknownA6 = Struct.uint32
self.unknownA7 = Struct.uint32
self.unknownA8 = Struct.uint32
self.unknownA9 = Struct.uint32
self.unknownB0 = Struct.uint32
self.unknownB1 = Struct.uint32
self.unknownB2 = Struct.uint32
self.unknownB3 = Struct.uint32
self.unknownB4 = Struct.uint32
self.unknownB5 = Struct.uint32
self.unknownB6 = Struct.uint32
self.unknownB7 = Struct.uint32
self.unknownB8 = Struct.uint32
self.unknownB9 = Struct.uint32
self.unknownC0 = Struct.uint32
self.unknownC1 = Struct.uint32
self.unknownC2 = Struct.uint32
self.unknownC3 = Struct.uint32
self.unknownC4 = Struct.uint32
self.unknownC5 = Struct.uint32
self.unknownC6 = Struct.uint32
self.unknownC7 = Struct.uint32
def __str__(self):
return_string = "Unknown00: %08x\n" % self.unknown00
return_string += "Unknown01: %08x\n" % self.unknown01
return_string += "Unknown02: %08x\n" % self.unknown02
return_string += "Unknown03: %08x\n" % self.unknown03
return_string += "Unknown04: %08x\n" % self.unknown04
return_string += "Unknown05: %08x\n" % self.unknown05
return_string += "Unknown06: %08x\n" % self.unknown06
return_string += "Unknown07: %08x\n" % self.unknown07
return_string += "Unknown08: %08x\n" % self.unknown08
return_string += "Unknown09: %08x\n" % self.unknown09
return_string += "Unknown10: %08x\n" % self.unknown10
return_string += "Unknown11: %08x\n" % self.unknown11
return_string += "Unknown12: %08x\n" % self.unknown12
return_string += "Unknown13: %08x\n" % self.unknown13
return_string += "Unknown14: %08x\n" % self.unknown14
return_string += "Unknown15: %08x\n" % self.unknown15
return_string += "Unknown16: %08x\n" % self.unknown16
return_string += "Unknown17: %08x\n" % self.unknown17
return_string += "Unknown18: %08x\n" % self.unknown18
return_string += "Unknown19: %08x\n" % self.unknown19
return_string += "Unknown20: %08x\n" % self.unknown20
return_string += "Unknown21: %08x\n" % self.unknown21
return_string += "Unknown22: %08x\n" % self.unknown22
return_string += "Unknown23: %08x\n" % self.unknown23
return_string += "Unknown24: %08x\n" % self.unknown24
return_string += "Unknown25: %08x\n" % self.unknown25
return_string += "Unknown26: %08x\n" % self.unknown26
return_string += "Unknown27: %08x\n" % self.unknown27
return_string += "Unknown28: %08x\n" % self.unknown28
return_string += "Unknown29: %08x\n" % self.unknown29
return_string += "Unknown30: %08x\n" % self.unknown30
return_string += "Unknown31: %08x\n" % self.unknown31
return_string += "Unknown32: %08x\n" % self.unknown32
return_string += "Unknown33: %08x\n" % self.unknown33
return_string += "Unknown34: %08x\n" % self.unknown34
return_string += "Unknown35: %08x\n" % self.unknown35
return_string += "Unknown36: %08x\n" % self.unknown36
return_string += "Unknown37: %08x\n" % self.unknown37
return_string += "Unknown38: %08x\n" % self.unknown38
return_string += "Unknown39: %08x\n" % self.unknown39
return_string += "Unknown40: %08x\n" % self.unknown40
return_string += "Unknown41: %08x\n" % self.unknown41
return_string += "Unknown42: %08x\n" % self.unknown42
return_string += "Unknown43: %08x\n" % self.unknown43
return_string += "Unknown44: %08x\n" % self.unknown44
return_string += "Unknown45: %08x\n" % self.unknown45
return_string += "Unknown46: %08x\n" % self.unknown46
return_string += "Unknown47: %08x\n" % self.unknown47
return_string += "Unknown48: %08x\n" % self.unknown48
return_string += "Unknown49: %08x\n" % self.unknown49
return_string += "Unknown50: %08x\n" % self.unknown50
return_string += "Unknown51: %08x\n" % self.unknown51
return_string += "Unknown52: %08x\n" % self.unknown52
return_string += "Unknown53: %08x\n" % self.unknown53
return_string += "Unknown54: %08x\n" % self.unknown54
return_string += "Unknown55: %08x\n" % self.unknown55
return_string += "Unknown56: %08x\n" % self.unknown56
return_string += "Unknown57: %08x\n" % self.unknown57
return_string += "Unknown58: %08x\n" % self.unknown58
return_string += "Unknown59: %08x\n" % self.unknown59
return_string += "Unknown60: %08x\n" % self.unknown60
return_string += "Unknown61: %08x\n" % self.unknown61
return_string += "Unknown62: %08x\n" % self.unknown62
return_string += "Unknown63: %08x\n" % self.unknown63
return_string += "Unknown64: %08x\n" % self.unknown64
return_string += "Unknown65: %08x\n" % self.unknown65
return_string += "Unknown66: %08x\n" % self.unknown66
return_string += "Unknown67: %08x\n" % self.unknown67
return_string += "Unknown68: %08x\n" % self.unknown68
return_string += "Unknown69: %08x\n" % self.unknown69
return_string += "Unknown70: %08x\n" % self.unknown70
return_string += "Unknown71: %08x\n" % self.unknown71
return_string += "Unknown72: %08x\n" % self.unknown72
return_string += "Unknown73: %08x\n" % self.unknown73
return_string += "Unknown74: %08x\n" % self.unknown74
return_string += "Unknown75: %08x\n" % self.unknown75
return_string += "Unknown76: %08x\n" % self.unknown76
return_string += "Unknown77: %08x\n" % self.unknown77
return_string += "Unknown78: %08x\n" % self.unknown78
return_string += "Unknown79: %08x\n" % self.unknown79
return_string += "Unknown80: %08x\n" % self.unknown80
return_string += "Unknown81: %08x\n" % self.unknown81
return_string += "Unknown82: %08x\n" % self.unknown82
return_string += "Unknown83: %08x\n" % self.unknown83
return_string += "Unknown84: %08x\n" % self.unknown84
return_string += "Unknown85: %08x\n" % self.unknown85
return_string += "Unknown86: %08x\n" % self.unknown86
return_string += "Unknown87: %08x\n" % self.unknown87
return_string += "Unknown88: %08x\n" % self.unknown88
return_string += "Unknown89: %08x\n" % self.unknown89
return_string += "Unknown90: %08x\n" % self.unknown90
return_string += "Unknown91: %08x\n" % self.unknown91
return_string += "Unknown92: %08x\n" % self.unknown92
return_string += "Unknown93: %08x\n" % self.unknown93
return_string += "Unknown94: %08x\n" % self.unknown94
return_string += "Unknown95: %08x\n" % self.unknown95
return_string += "Unknown96: %08x\n" % self.unknown96
return_string += "Unknown97: %08x\n" % self.unknown97
return_string += "Unknown98: %08x\n" % self.unknown98
return_string += "Unknown99: %08x\n" % self.unknown99
return_string += "UnknownA0: %08x\n" % self.unknownA0
return_string += "UnknownA1: %08x\n" % self.unknownA1
return_string += "UnknownA2: %08x\n" % self.unknownA2
return_string += "UnknownA3: %08x\n" % self.unknownA3
return_string += "UnknownA4: %08x\n" % self.unknownA4
return_string += "UnknownA5: %08x\n" % self.unknownA5
return_string += "UnknownA6: %08x\n" % self.unknownA6
return_string += "UnknownA7: %08x\n" % self.unknownA7
return_string += "UnknownA8: %08x\n" % self.unknownA8
return_string += "UnknownA9: %08x\n" % self.unknownA9
return_string += "UnknownB0: %08x\n" % self.unknownB0
return_string += "UnknownB1: %08x\n" % self.unknownB1
return_string += "UnknownB2: %08x\n" % self.unknownB2
return_string += "UnknownB3: %08x\n" % self.unknownB3
return_string += "UnknownB4: %08x\n" % self.unknownB4
return_string += "UnknownB5: %08x\n" % self.unknownB5
return_string += "UnknownB6: %08x\n" % self.unknownB6
return_string += "UnknownB7: %08x\n" % self.unknownB7
return_string += "UnknownB8: %08x\n" % self.unknownB8
return_string += "UnknownB9: %08x\n" % self.unknownB9
return_string += "UnknownC0: %08x\n" % self.unknownC0
return_string += "UnknownC1: %08x\n" % self.unknownC1
return_string += "UnknownC2: %08x\n" % self.unknownC2
return_string += "UnknownC3: %08x\n" % self.unknownC3
return_string += "UnknownC4: %08x\n" % self.unknownC4
return_string += "UnknownC5: %08x\n" % self.unknownC5
return_string += "UnknownC6: %08x\n" % self.unknownC6
return_string += "UnknownC7: %08x\n" % self.unknownC7
return return_string
class BREFT_REFT_StringSection1(Struct):
__endian__ = Struct.BE
def __format__(self):
self.offset = Struct.uint32
self.length = Struct.uint32
def __str__(self):
return_string = "Offset: %08x\n" % self.offset
return_string += "Length: %08x\n" % self.length
return return_string
class BREFT_REFT_StringHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.offset = Struct.uint16
self.length = Struct.uint16
self.string_cnt = Struct.uint16
self.unknown01 = Struct.uint16
def __str__(self):
return_string = "Offset: %04x\n" % self.offset
return_string += "Offset: %04x\n" % self.length
return_string += "String Count: %04x\n" % self.string_cnt
return_string += "Unknown01: %04x" % self.unknown01
return return_string
class BREFT_REFT_Project(Struct):
__endian__ = Struct.BE
def __format__(self):
self.length = Struct.uint32
self.unknown01 = Struct.uint32
self.unknown02 = Struct.uint32
self.str_length = Struct.uint16
self.unknown03 = Struct.uint16
def __str__(self):
return_string = "Length: %08x\n" % self.length
return_string += "Unknown01: %08x\n" % self.unknown01
return_string += "Unknown02: %08x\n" % self.unknown02
return_string += "Number of Strings: %04x\n" % self.str_length
return_string += "Unknown: %04x" % self.unknown03
return return_string
class BREFT_REFT(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.length = Struct.uint32
def __str__(self):
return_string = "Magic: %s\n" % self.magic
return_string += "Length: %08x\n" % self.length
return return_string
class BREFT_Header(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.version = Struct.uint32
self.length = Struct.uint32
self.header_size = Struct.uint16
self.chunk_cnt = Struct.uint16
def __str__(self):
return_string = "Magic: %s\n" % self.magic
return_string += "Version: %08x\n" % self.version
return_string += "Length: %08x\n" % self.length
return_string += "Header Size: %04x\n" % self.header_size
return_string += "Chunk Count: %04x\n" % self.chunk_cnt
return return_string
def __init__(self, data):
self.data = []
if data != None:
self.Unpack(data)
def Unpack(self, data):
pos = 0
header = self.BREFT_Header()
header.unpack(data[pos:pos+len(header)])
pos += len(header)
print header
assert header.magic == "REFT"
assert header.version == 0xfeff0004
reft = self.BREFT_REFT()
reft.unpack(data[pos:pos+len(reft)])
pos += len(reft)
print reft
assert reft.magic == "REFT"
print "\n%08x\n" % pos
reft_project = self.BREFT_REFT_Project()
reft_project.unpack(data[pos:pos+len(reft_project)])
pos += len(reft_project)
print reft_project
string = nullterm(data[pos:pos+reft_project.str_length])
pos += reft_project.str_length
print "String: %s\n" % string
while pos %2:
unknown = Struct.uint8(data[pos:pos+1])
pos += 1
print "Padding: %02x" % unknown
print "\n%08x\n" % pos
for x in xrange(0x30):
pad = Struct.uint8(data[pos:pos+1])
pos += 1
#print "Padding: %08x" % pad
print "\n%08x\n" % pos
temp = pos
reft_string_header = self.BREFT_REFT_StringHeader()
reft_string_header.unpack(data[pos:pos+len(reft_string_header)])
pos += len(reft_string_header)
print reft_string_header
print "\n%08x\n" % pos
string_groups = []
for x in xrange(reft_string_header.string_cnt):
str_length = Struct.uint16(data[pos:pos+2], endian='>')
pos += 2
print "String Length with null added: %04x" % str_length
string = nullterm(data[pos:pos+str_length])
pos += str_length
print "String: %s" % string
string_section1 = self.BREFT_REFT_StringSection1()
string_section1.unpack(data[pos:pos+len(string_section1)])
pos += len(string_section1)
print string_section1
string_groups.append(string_section1)
for x in xrange(reft_string_header.string_cnt):
pos = temp + string_groups[x].offset
print "\n%08x\n" % pos
reft_section2 = self.BREFT_REFT_Section2()
reft_section2.unpack(data[pos:pos+len(reft_section2)])
pos += len(reft_section2)
print reft_section2
print "\n%08x\n" % pos
#''' BEGIN TEST DATA
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
unknown = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
print "Unknown: %08x" % unknown
#END TEST DATA '''
def main():
if len(sys.argv) != 2:
print 'Usage: python breft.py <filename>'
sys.exit(1)
f = open(sys.argv[1], 'rb')
if f:
reft = f.read()
f.close()
assert reft[0:8] == 'REFT\xfe\xff\x00\x04'
breft = BREFT(reft)
else:
print 'Could not open %s' % sys.argv[1]
sys.exit(1)
if __name__ == "__main__":
main()

108
WiiPy/experimental/csv.py Executable file
View File

@ -0,0 +1,108 @@
#!/usr/bin/python
import sys, re, struct
from Struct import Struct
def nullterm(str_plus):
z = str_plus.find('\x00\x09')
if z != -1:
return str_plus[:z]
else:
return str_plus
def denullterm(str_plus):
z = str_plus.find('\x0a\x0a')
if z != -1:
return str_plus[:z]
else:
return str_plus
class CSV(object):
def __init__(self, data=None, outfile=None, debug=False):
self.data = []
if data != None:
self.Unpack(data, outfile, debug)
def Unpack(self, data, outfile=None, debug=False):
if outfile != None:
file = open(outfile, 'wb')
pos = 0
version = Struct.uint16(data[pos:pos+2], endian='>')
pos += 2
if debug == True:
print "Version: %04x" % version
print
self.string_list = []
while pos < len(data):
string = nullterm(data[pos:])
string = unicode(string, 'utf_16_be')
if debug == True:
print "String: %s" % string
pos += len(string) * 2 + 2
self.string_list.append(string)
file.write(string.encode('utf-8'))
file.write('\n')
if pos < len(data):
file.write('\n')
file.close()
def write(self, data, output_file):
file = open(output_file, 'wb')
if file:
file.write('\xfe\xff')
pos = 0
while pos < len(data):
temp = denullterm(data[pos:])
pos += len(temp) + 2
string = unicode(temp, 'utf-8')
file.write(string.encode('utf_16_be'))
if pos < len(data):
file.write('\x00\x09')
else:
file.write('\x00\x0a')
file.close()
else:
print "Could not open file for writing"
sys.exit(1)
def main():
if len(sys.argv) == 1:
print 'Usage: python -r csv.py <filename.csv> <filename.hog>'
print ' == OR == '
print 'Usage: python -w csv.py <filename.hog> <filename.csv>'
sys.exit(1)
if sys.argv[1] == "-r":
f = open(sys.argv[2], 'rb')
if f:
csv_buffer = f.read()
f.close()
else:
print 'Could not open file for reading'
sys.exit(1)
csv = CSV(csv_buffer, outfile=sys.argv[3], debug=False)
elif sys.argv[1] == "-w":
f = open(sys.argv[2], 'rb')
if f:
input_file = f.read()
f.close()
else:
print 'Could not open file for reading'
sys.exit(1)
csv = CSV()
csv.write(input_file, sys.argv[3])
else:
print 'Usage: python -r csv.py <filename.csv> <filename.hog>'
print ' == OR == '
print 'Usage: python -w csv.py <filename.hog> <filename.csv>'
sys.exit(1)
if __name__ == "__main__":
main()

182
WiiPy/experimental/thp.py Normal file
View File

@ -0,0 +1,182 @@
from Struct import *
from pyglet import clock, window, image
from pyglet.gl import *
import cStringIO
import math
from time import time
class THP():
class THPHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.version = Struct.uint32
self.bufSize = Struct.uint32
self.audioMaxSamples = Struct.uint32
self.frameRate = Struct.float
self.numFrames = Struct.uint32
self.firstFrameSize = Struct.uint32
self.movieDataSize = Struct.uint32
self.compInfoDataOffsets = Struct.uint32
self.offsetDataOffsets = Struct.uint32 #Offset to a offset table, containing offsets to each frame, this allows for starting playback from any frame. If this is 0 then it does not exist.
self.movieDataOffsets = Struct.uint32
self.finalFrameDataOffsets = Struct.uint32
def __str__(self):
ret = "\n"
ret += "Magic: %s\n" % self.magic
ret += "Version: %d.%d.%d\n" % (((self.version & 0xFFFF0000) >> 16), ((self.version & 0xFF00) >> 8), ((self.version & 0xFF)))
ret += "bufSize: %s\n" % self.bufSize
ret += "audioMaxSamples: %d\n" % self.audioMaxSamples
ret += "frameRate: %f\n" % self.frameRate
ret += "numFrames: %d\n" % self.numFrames
ret += "firstFrameSize: %d\n" % self.firstFrameSize
ret += "movieDataSize: %d\n" % self.movieDataSize
ret += "compInfoDataOffsets: 0x%08X\n" % self.compInfoDataOffsets
ret += "offsetDataOffsets: 0x%08X\n" % self.offsetDataOffsets
ret += "movieDataOffsets: 0x%08X\n" % self.movieDataOffsets
ret += "finalFrameDataOffsets: 0x%08X\n" % self.finalFrameDataOffsets
return ret
class THPFrameCompInfo(Struct):
__endian__ = Struct.BE
def __format__(self):
self.numComponents = Struct.uint32
self.frameComp = Struct.uint8[16]
def __str__(self):
ret = ""
ret += "Number of Components: %d\n" % self.numComponents
return ret
class THPCompVideoInfo(Struct):
__endian__ = Struct.BE
def __format__(self):
self.width = Struct.uint32
self.height = Struct.uint32
self.videoType = Struct.uint32
def __str__(self):
tempType = ("Non-Interlaced", "Interlaced", "Odd Interlace", "3", "Even Interlace")
ret = ""
ret += "Width: %d\n" % self.width
ret += "Height: %d\n" % self.height
ret += "VideoType: %s\n" % tempType[self.videoType]
return ret
class THPCompAudioInfo(Struct):
__endian__ = Struct.BE
def __format__(self):
self.sndChannels = Struct.uint32
self.sndFrequency = Struct.uint32
self.sndNumberSamples = Struct.uint32
self.sndNumberTracks = Struct.uint32
def __str__(self):
ret = ""
ret += "Channels: %d\n" % self.sndChannels
ret += "Frequency: %d\n" % self.sndFrequency
ret += "Samples: %d\n" % self.sndNumberSamples
ret += "Tracks: %d\n" % self.sndNumberTracks
return ret
class THPFrameHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.frameSizeNext = Struct.uint32
self.frameSizePrev = Struct.uint32
self.vidFileSize = Struct.uint32
self.sndFileSize = Struct.uint32
def __str__(self):
ret = ""
ret += "next Frame Size: %d\n" % self.frameSizeNext
ret += "previous Frame Size: %d\n" % self.frameSizePrev
ret += "Video frame data size: %d\n" % self.vidFileSize
ret += "Track file size: %d\n" % self.sndFileSize
return ret
def readData(self, fp, i=0):
self.frameImage = fp.read(self.vidFileSize)
#fileName = "frame%06d.jpg" % i
#open("out/" + fileName, 'w+b').write(self.frameImage)
#print "Frame: %d" % i
startTime = time()
start = self.frameImage.find('\xff\xda')
end = self.frameImage.rfind('\xff\xd9')
#print "find(%d): This took "%i, time()-startTime,start,end
startTime = time()
startStr = self.frameImage[:start+2]
endStr = self.frameImage[end:]
#print "extr(%d): This took "%i, time()-startTime
self.frameImage = self.frameImage[start+2:end]
self.frameImage = startStr + self.frameImage.replace('\xff','\xff\x00') + endStr
#print self.frameImage
return cStringIO.StringIO(self.frameImage)
def __init__(self, movieFile=None):
if(movieFile==None):
print "Usage: python thp.py filename.thp"
exit(-1)
fp = file(movieFile, 'rb')
HEADER = self.THPHeader()
HEADER.unpack(fp.read(len(HEADER)))
print HEADER
fp.seek(HEADER.compInfoDataOffsets)
CompInfo = self.THPFrameCompInfo()
CompInfo.unpack(fp.read(len(CompInfo)))
print CompInfo
for i in range(0, CompInfo.numComponents):
if(CompInfo.frameComp[i] == 0):
VideoInfo = self.THPCompVideoInfo()
VideoInfo.unpack(fp.read(len(VideoInfo)))
print VideoInfo
if(CompInfo.frameComp[i] == 1):
AudioInfo = self.THPCompAudioInfo()
AudioInfo.unpack(fp.read(len(AudioInfo)))
print AudioInfo
clock.set_fps_limit(HEADER.frameRate)
currOff = HEADER.movieDataOffsets
currSize = HEADER.firstFrameSize
fp.seek(currOff)
win = window.Window(VideoInfo.width, VideoInfo.height)
fps_display = clock.ClockDisplay()
i = 1
j = 1
image_index = 0
image_period = 1.0 / HEADER.frameRate # Reciprocal of the frame rate
remained = 0
while not win.has_exit:
win.dispatch_events()
win.clear()
dt = clock.tick()
skip = math.floor((dt+remained)/image_period)
j += skip
print skip, ":break:", i, j, skip
remained = dt - skip * image_period
tempFrame = self.THPFrameHeader()
tempFrame.unpack(fp.read(len(tempFrame)))
for xx in range(1,skip):
currOff = currOff+currSize
currSize = tempFrame.frameSizeNext
fp.seek(currOff)
tempFrame = self.THPFrameHeader()
tempFrame.unpack(fp.read(len(tempFrame)))
imagedat = tempFrame.readData(fp, i)
pic = image.load("image.jpg",imagedat)
pic.blit(0,0)
currOff = currOff+currSize
currSize = tempFrame.frameSizeNext
fp.seek(currOff)
fps_display.draw()
win.flip()
i += 1
if __name__=='__main__':
THP(*sys.argv[1:])

123
WiiPy/experimental/znd.py Executable file
View File

@ -0,0 +1,123 @@
#!/usr/bin/python
import sys, re, struct
from Struct import Struct
def nullterm(str_plus):
z = str_plus.find('\x00\x00')
if z != -1:
return str_plus[:z]
else:
return str_plus
def denullterm(str_plus):
z = str_plus.find('\x0a')
if z != -1:
return str_plus[:z]
else:
return str_plus
class ZND(object):
def __init__(self, data=None, out_file=None, debug=False):
self.data = []
if data != None:
self.Unpack(data, out_file, debug)
def Unpack(self, data, out_file, debug=False):
file = open(out_file, 'wb')
if file:
pos = 0
count = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
if debug == True:
print "Count: %08x" % count
print "\n%08x\n" % pos
offset_list = []
for x in xrange(count):
offset = Struct.uint32(data[pos:pos+4], endian='>')
pos += 4
if debug == True:
print "Offset: %08x" % offset
offset_list.append(offset)
if debug == True:
print "\n%08x\n" % pos
for x in xrange(count):
pos = offset_list[x]
string = nullterm(data[pos:])
string = unicode(string, 'utf_16_be')
if debug == True:
print "String: %s" % string.encode('utf-8')
pos += len(string)
file.write(string.encode('utf-8'))
file.write('\n')
file.close()
else:
print "Could not open file for writing"
sys.exit(1)
def write(self, data, out_file):
file = open(out_file, 'wb')
if file:
pos = 0
count = 0
string_list = []
while pos < len(data):
temp = denullterm(data[pos:])
pos += len(temp) + 1
string = unicode(temp, 'utf-8')
string_list.append(string)
count += 1
file.write(struct.pack('>I', count))
pos = count * 4 + 4
for x in xrange(count):
file.write(struct.pack('>I', pos))
pos += len(string_list[x]) * 2 + 2
for x in xrange(count):
file.write(string_list[x].encode('utf_16_be'))
file.write('\x00\x00')
while pos % 0x20:
pos += 2
file.write('\x00\x00')
file.close()
else:
print "Could not open file for writing"
sys.exit(1)
def main():
if len(sys.argv) == 1:
print 'Usage: python znd.py -r <filename.znd> <filename.hog>'
print ' == OR == '
print 'Usage: python znd.py -w <filename.hog> <filename.znd>'
sys.exit(1)
if sys.argv[1] == "-r":
f = open(sys.argv[2], 'rb')
if f:
znd_buffer = f.read()
f.close()
else:
print 'Could not open file for reading'
sys.exit(1)
znd = ZND(znd_buffer, sys.argv[3], debug=False)
elif sys.argv[1] == "-w":
f = open(sys.argv[2], 'rb')
if f:
buffer = f.read()
f.close()
else:
print 'Could not open file for reading'
sys.exit(1)
znd = ZND()
znd.write(buffer, sys.argv[3])
else:
print 'Usage: python znd.py -r <filename.znd> <filename.hog>'
print ' == OR == '
print 'Usage: python znd.py -w <filename.hog> <filename.znd>'
sys.exit(1)
if __name__ == "__main__":
main()

253
WiiPy/export.py Normal file
View File

@ -0,0 +1,253 @@
from common import *
from title import *
from image import *
class Savegame():
class savegameHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.savegameId = Struct.uint32[2]
self.bannerSize = Struct.uint32
self.permissions = Struct.uint8
self.unknown1 = Struct.uint8
self.md5hash = Struct.string(16)
self.unknown2 = Struct.uint16
class savegameBanner(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.reserved = Struct.uint8[4]
self.flags = Struct.uint32
self.reserved = Struct.uint32[5]
self.gameTitle = Struct.string(64)
self.gameSubTitle = Struct.string(64)
self.banner = Struct.string(24576)
self.icon0 = Struct.string(4608)
self.icon1 = Struct.string(4608)
self.icon2 = Struct.string(4608)
self.icon3 = Struct.string(4608)
self.icon4 = Struct.string(4608)
self.icon5 = Struct.string(4608)
self.icon6 = Struct.string(4608)
self.icon7 = Struct.string(4608)
class backupHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.hdrSize = Struct.uint32
self.magic = Struct.string(2)
self.version = Struct.uint16
self.NGid = Struct.uint32
self.filesCount = Struct.uint32
self.filesSize = Struct.uint32
self.unknown1 = Struct.uint32
self.unknown2 = Struct.uint32
self.totalSize = Struct.uint32
self.unknown3 = Struct.uint8[64]
self.unknown4 = Struct.uint32
self.gameId = Struct.string(4)
self.wiiMacAddr = Struct.uint8[6]
self.unknown6 = Struct.uint16
self.padding = Struct.uint32[4]
class fileHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.uint32
self.size = Struct.uint32
self.permissions = Struct.uint8
self.attribute = Struct.uint8
self.type = Struct.uint8
self.nameIV = Struct.string(0x45)
def __init__(self, f):
self.f = f
try:
self.fd = open(f, 'r+b')
except:
raise Exception('Cannot open input')
self.sdKey = '\xab\x01\xb9\xd8\xe1\x62\x2b\x08\xaf\xba\xd8\x4d\xbf\xc2\xa5\x5d'
self.sdIv = '\x21\x67\x12\xe6\xaa\x1f\x68\x9f\x95\xc5\xa2\x23\x24\xdc\x6a\x98'
self.iconCount = 1
def __str__(self):
ret = ''
ret += '\nSavegame header \n'
ret += 'Savegame ID : 0x%x%x\n' % (self.hdr.savegameId[0], self.hdr.savegameId[1])
ret += 'Banner size : 0x%x\n' % self.hdr.bannerSize
ret += 'Permissions : 0x%x\n' % self.hdr.permissions
ret += 'Unknown : 0x%x\n' % self.hdr.unknown1
ret += 'MD5 hash : %s\n' % hexdump(self.hdr.md5hash)
ret += 'Unknown : 0x%x\n' % self.hdr.unknown2
ret += '\nBanner header \n'
ret += 'Flags : 0x%x\n' % self.bnr.flags
ret += 'Game title : %s\n' % self.bnr.gameTitle
ret += 'Game subtitle : %s\n' % self.bnr.gameSubTitle
ret += 'Icons found : %i\n' % self.iconCount
ret += '\nBackup header \n'
ret += 'Header size : 0x%x (+ 0x10 of padding) version 0x%x\n' % (self.bkHdr.hdrSize, self.bkHdr.version)
if self.bkHdr.gameId[3] == 'P':
ret += 'Region : PAL\n'
elif self.bkHdr.gameId[3] == 'E':
ret += 'Region : NTSC\n'
elif self.bkHdr.gameId[3] == 'J':
ret += 'Region : JAP\n'
ret += 'Game ID : %s\n' % self.bkHdr.gameId
ret += 'Wii unique ID : 0x%x\n' % self.bkHdr.NGid
ret += 'Wii MAC address %02x:%02x:%02x:%02x:%02x:%02x\n' % (self.bkHdr.wiiMacAddr[0], self.bkHdr.wiiMacAddr[1], self.bkHdr.wiiMacAddr[2], self.bkHdr.wiiMacAddr[3], self.bkHdr.wiiMacAddr[4], self.bkHdr.wiiMacAddr[5])
ret += 'Found %i files for %i bytes\n' % (self.bkHdr.filesCount, self.bkHdr.filesSize)
ret += 'Total size : %i bytes\n' % self.bkHdr.totalSize
ret += 'This save is %i blocks wise' % (self.bkHdr.totalSize / 0x20000)
return ret
def extractFiles(self):
try:
os.mkdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
except:
pass
os.chdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
self.fd.seek(self.fileStartOffset)
for i in range(self.bkHdr.filesCount):
fileHdr = self.fd.read(0x80)
fileHdr = self.fileHeader().unpack(fileHdr)
if fileHdr.magic != 0x03adf17e:
raise Exception('Wrong file magic')
fileHdr.size = align(fileHdr.size, 64)
ivpos = 0
name = ""
i = 0
for char in list(fileHdr.nameIV):
if(char == "\x00"):
i -= 1
ivpos = i
break
else:
name += char
i += 1
fileIV = fileHdr.nameIV[ivpos:ivpos + 16]
if len(fileIV) != 16:
raise Exception('IV alignment issue')
if fileHdr.type == 1:
print 'Extracted %s (%ib)' % (name, fileHdr.size)
fileBuffer = self.fd.read(fileHdr.size)
fileBuffer = Crypto().decryptData(self.sdKey, fileIV, fileBuffer, True)
try:
open(name, 'w+b').write(fileBuffer)
except:
raise Exception('Cannot write the output')
elif fileHdr.type == 2:
print 'Extracted folder %s' % name
try:
os.mkdir(name)
except:
pass
print 'Attribute %i Permission %i' % (fileHdr.attribute, fileHdr.permissions)
print 'File IV : 0x%s' % hexdump(fileIV, '')
os.chdir('..')
def analyzeHeader(self):
headerBuffer = self.fd.read(0xF0C0)
headerBuffer = Crypto().decryptData(self.sdKey, self.sdIv, headerBuffer, True)
self.hdr = self.savegameHeader().unpack(headerBuffer[:0x20])
#headerBuffer.replace(self.hdr.md5hash, '\x0e\x65\x37\x81\x99\xbe\x45\x17\xab\x06\xec\x22\x45\x1a\x57\x93')
#print 'Reashed md5 : %s' % hexdump(Crypto().createMD5Hash(headerBuffer))
self.bnr = self.savegameBanner().unpack(headerBuffer[0x20:])
if self.bnr.magic != 'WIBN':
raise Exception ('Wrong magic, should be WIBN')
if self.hdr.bannerSize != 0x72A0:
self.iconCount += 7
bkHdrBuffer = self.fd.read(0x80)
self.bkHdr = self.backupHeader().unpack(bkHdrBuffer)
if self.bkHdr.magic != 'Bk' or self.bkHdr.hdrSize != 0x70:
raise Exception ('Bk header error')
self.fileStartOffset = self.fd.tell()
def eraseWiiMac(self):
self.fd.seek(0xF128)
print self.fd.write('\x00' * 6)
def getBanner(self):
try:
os.mkdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
except:
pass
os.chdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
return Image.fromstring("RGBA", (192, 64), TPL('').RGB5A3((192, 64), self.bnr.banner)).save('banner', 'png')
def getIcon(self, index):
if index < 0 or index > 7 or index > self.iconCount:
return -1
try:
os.mkdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
except:
pass
os.chdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
if index == 0:
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon0)).save('icon' + str(index), 'png')
if index == 1:
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon1)).save('icon' + str(index), 'png')
if index == 2:
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon2)).save('icon' + str(index), 'png')
if index == 3:
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon3)).save('icon' + str(index), 'png')
if index == 4:
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon4)).save('icon' + str(index), 'png')
if index == 5:
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon5)).save('icon' + str(index), 'png')
if index == 6:
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon6)).save('icon' + str(index), 'png')
if index == 7:
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon7)).save('icon' + str(index), 'png')
def getIconsCount(self):
return self.iconCount
def getSaveString(self, string):
if string == 'id':
return self.bkHdr.gameId
elif string == 'title':
return self.bnr.gameTitle
elif string == 'subtitle':
return self.bnr.gameSubTitle
elif string == 'mac':
return self.bkHdr.wiiMacAddr[0] + ':' + self.bkHdr.wiiMacAddr[1] + ':' + self.bkHdr.wiiMacAddr[2] + ':' + self.bkHdr.wiiMacAddr[3] + ':' + self.bkHdr.wiiMacAddr[4] + ':' + self.bkHdr.wiiMacAddr[5]
def getFilesCount(self):
return self.bkHdr.filesCount

887
WiiPy/formats.py Normal file
View File

@ -0,0 +1,887 @@
from binascii import *
import struct
from common import *
from title import *
class locDat:
class locHeader(Struct):
def __format__(self):
self.magic = Struct.string(4)
self.md5 = Struct.string(16)
def __init__(self, f):
self.sdKey = '\xab\x01\xb9\xd8\xe1\x62\x2b\x08\xaf\xba\xd8\x4d\xbf\xc2\xa5\x5d'
self.sdIv = '\x21\x67\x12\xe6\xaa\x1f\x68\x9f\x95\xc5\xa2\x23\x24\xdc\x6a\x98'
self.titles = []
self.usedBlocks = 0
self.freeBlocks = 0
try:
self.fp = open(f, 'r+')
except:
raise Exception('File not found')
plainBuffer = Crypto().decryptData(self.sdKey, self.sdIv, self.fp.read(), False)
self.hdr = self.locHeader().unpack(plainBuffer[:0x14])
for x in range(240):
self.titles.append(plainBuffer[0x14 + x * 4:0x14 + (x + 1) * 4])
if self.titles[x] == '\x00\x00\x00\x00':
self.freeBlocks += 1
self.usedBlocks = 240 - self.freeBlocks
def __str__(self):
out = ''
out += 'Used %i blocks out of 240\n\n' % self.usedBlocks
for x in range(240):
if self.titles[x] == '\x00\x00\x00\x00':
out += 'Block %i on page %i is empty\n' % (x, x / 12)
else:
out += 'Block %i on page %i hold title %s\n' % (x, x / 12, self.titles[x])
return out
def getFreeBlocks(self):
return self.freeBlocks
def getUsedBlocks(self):
return self.usedBlocks
def isBlockFree(self, x, y, page):
if self.titles[((x + (y * 4) + (page * 12)))] == '\x00\x00\x00\x00':
return 1
return 0
def isTitleInList(self, title):
try:
return self.titles.index(title.upper())
except:
return -1
def getPageTitles(self, page):
if page > 19:
raise Exception('Out of bounds')
return self.titles[12 * page:12 * (page + 1)]
def getTitle(self, x, y, page):
if x > 3 or y > 2 or page > 19:
raise Exception('Out of bounds')
return self.titles[((x + (y * 4) + (page * 12)))]
def setTitle(self, x, y, page, element):
if x > 3 or y > 2 or page > 19 or len(element) > 4:
raise Exception('Out of bounds')
self.titles[((x + (y * 4) + (page * 12)))] = element.upper()
titles = ''
titles += self.hdr.magic
titles += self.hdr.md5
for x in range(240):
titles += self.titles[x]
titles += '\x00' * 12
titles = titles[:0x4] + Crypto().createMD5Hash(titles) + titles[0x14:]
self.fp.seek(0)
self.fp.write(Crypto().encryptData(self.sdKey, self.sdIv, titles))
def delTitle(self, x, y, page):
self.setTitle(x, y, page, '\x00\x00\x00\x00')
class CONF:
"""This class deals with setting.txt which holds some important information like region and serial number """
def __init__(self, f):
self.conf = ''
self.keys = {}
self.lastKeyOffset = 0
self.totalKeys = 0
try:
self.fp = open(f, 'r+b')
except:
self.fp = open(f, 'w+b')
return
self.conf = self.fp.read(0x100)
self.conf = self.XORConf(self.conf)
self.fp.seek(0)
keys = self.conf.split('\r\n')
self.lastKeyOffset = self.conf.rfind('\r\n') + 2
self.totalKeys = len(keys) - 1
for x in range(self.totalKeys):
keyName = keys[x].split('=')[0]
keyVal = keys[x].split('=')[1]
self.keys[keyName] = keyVal
def getKeysCount(self):
"""Gets how many keys exist."""
return self.totalKeys
def getKeysName(self):
"""Returns the list of key names."""
return self.keys.keys()
def getKeyValue(self, key):
"""Returns the value of the key ``key''."""
try:
return self.keys[key.upper()]
except KeyError:
return 'Key not found'
def setKeyValue(self, key, value):
"""Sets the value of key ``key'' to ``value''."""
if(self.keyExist(key)):
self.keys[key.upper()] = value.upper()
self.conf = ''
for key in self.keys:
self.conf += key
self.conf += '='
self.conf += self.keys[key]
self.conf += '\r\n'
self.fp.seek(0)
self.fp.write(self.XORConf(self.conf))
self.fp.write('\x00' * (0x100 - len(self.conf)))
self.lastKeyOffset = self.conf.rfind('\r\n') + 2
def keyExist(self, key):
return self.keys.has_key(key.upper())
def addKey(self, key, value):
"""Adds key ``key'' with value ``value'' to the list."""
if self.lastKeyOffset + len(key) + 1 + len(value) + 2 > 0x100:
return -1
if not self.keyExist(key):
return -2
self.keys[key.upper()] = value.upper()
self.totalKeys +=1
self.conf = self.conf[:self.lastKeyOffset] + key.upper() + '=' + value.upper() + '\r\n'
self.lastKeyOffset += len(key) + 1 + len(value) + 2
self.fp.seek(0)
self.fp.write(self.XORConf(self.conf))
def XORConf(self, conf):
"""Encrypts/decrypts the setting.txt file."""
XORKey = 0x73B5DBFA
out = ''
for x in range(len(conf)):
out += chr(ord(conf[x]) ^ XORKey & 0xFF)
XORKey = (XORKey << 1) | (XORKey >> 31)
return out
def deleteKey(self, key):
"""Deletes the key ``key''."""
try:
del self.keys[key.upper()]
self.totalKeys -=1
self.conf = ''
for key in self.keys:
self.conf += key
self.conf += '='
self.conf += self.keys[key]
self.conf += '\r\n'
self.fp.seek(0)
self.fp.write(self.XORConf(self.conf))
self.fp.write('\x00' * (0x100 - len(self.conf)))
self.lastKeyOffset = self.conf.rfind('\r\n') + 2
except KeyError:
return 'Key not found'
# This function is fucking dangerous. It deletes all keys with that value. Really not a good idea.
def deleteKeyByValue(self, value):
"""Deletes all keys with value ``value''. WATCH OUT, YOU MIGHT ACCIDENTALLY DELETE WRONG KEYS."""
try:
for key in self.keys.keys():
if self.keys.get(key) == value:
del self.keys[key]
self.totalKeys -=1
self.conf = ''
for key in self.keys:
self.conf += key
self.conf += '='
self.conf += self.keys[key]
self.conf += '\r\n'
self.fp.seek(0)
self.fp.write(self.XORConf(self.conf))
self.fp.write('\x00' * (0x100 - len(self.conf)))
self.lastKeyOffset = self.conf.rfind('\r\n') + 2
except KeyError:
return 'Key not found'
def getRegion(self):
"""gets the Region key. (Shortcut for getKeyValue("GAME"))"""
return self.getKeyValue("GAME")
def getArea(self):
"""gets the Area key. (Shortcut for getKeyValue("AREA"))"""
return self.getKeyValue("AREA")
def getVideoMode(self):
"""gets the Video Mode key. (Shortcut for getKeyValue("VIDEO"))"""
return self.getKeyValue("VIDEO")
def getSerialCode(self):
"""gets the Serial Code key. (Shortcut for getKeyValue("CODE"))"""
return self.getKeyValue("CODE")
def getDVDModel(self): # Might not be model =/
"""gets the DVD Model (?) key. (Shortcut for getKeyValue("DVD"))"""
return self.getKeyValue("DVD")
def getHardwareModel(self):
"""gets the Hardware Model key. (Shortcut for getKeyValue("MODEL"))"""
return self.getKeyValue("MODEL")
def getSerialNumber(self):
"""gets the Serial Number key. (Shortcut for getKeyValue("SERNO"))"""
return self.getKeyValue("SERNO")
def setRegion(self, value):
"""sets the Region key. (Shortcut for setKeyValue("GAME", value))"""
return self.setKeyValue("GAME", value)
def setArea(self, value):
"""sets the Area key. (Shortcut for setKeyValue("AREA", value))"""
return self.setKeyValue("AREA", value)
def setVideoMode(self, value):
"""sets the Video Mode key. (Shortcut for setKeyValue("VIDEO", value))"""
return self.setKeyValue("VIDEO", value)
def setSerialCode(self, value):
"""sets the Serial Code key. (Shortcut for setKeyValue("CODE", value))"""
return self.setKeyValue("CODE", value)
def setDVDModel(self, value): # Might not be model =/
"""sets the DVD Model (?) key. (Shortcut for setKeyValue("DVD", value))"""
return self.setKeyValue("DVD", value)
def setHardwareModel(self, value):
"""sets the Hardware Model key. (Shortcut for setKeyValue("MODEL", value))"""
return self.setKeyValue("MODEL", value)
def setSerialNumber(self, value):
"""sets the Serial Number key. (Shortcut for setKeyValue("SERNO", value))"""
return self.setKeyValue("SERNO", value)
class netConfig:
"""This class performs network configuration. The file is located on the NAND at /shared2/sys/net/02/config.dat."""
class configEntry(Struct):
__endian__ = Struct.BE
def __format__(self):
self.selected = Struct.uint8
self.padding_1 = Struct.string(1987)
self.ssid = Struct.string(32)
self.padding_2 = Struct.uint8
self.ssid_len = Struct.uint8
self.padding_3 = Struct.string(2)
self.padding_4 = Struct.uint8
self.encryption = Struct.uint8 # OPEN: 0x00, WEP: 0x01, WPA-PSK (TKIP): 0x04, WPA2-PSK (AES): 0x05, WPA-PSK (AES): 0x06
self.padding_5 = Struct.string(2)
self.padding_6 = Struct.uint8
self.key_len = Struct.uint8
self.padding_7 = Struct.string(2)
self.key = Struct.string(64)
self.padding_3 = Struct.string(236)
def __init__(self, conf):
self.f = conf
if(not os.path.isfile(self.f)):
fp = open(self.f, "wb")
fp.write("\x00\x00\x00\x00\x01\x07\x00\x00")
fp.write("\x00" * 0x91C * 3)
fp.close()
fp = open(self.f, "rb")
head = fp.read(8)
if(head != "\x00\x00\x00\x00\x01\x07\x00\x00"):
print("Config file is invalid!\n")
def getNotBlank(self, config):
fp = open(self.f, "rb")
fp.seek(8 + (0x91C * config))
sel = struct.unpack(">B", fp.read(1))[0]
fp.close()
if(sel & 0x20):
return 1
return 0
def getIPType(self, config):
if(not self.getNotBlank(config)):
return None
fp = open(self.f, "rb")
fp.seek(8 + (0x91C * config))
sel = struct.unpack(">B", fp.read(1))[0]
if(sel & 0x04):
return 0
else:
return 1
fp.close()
return sel
def getWireType(self, config):
if(not self.getNotBlank(config)):
return None
fp = open(self.f, "rb")
fp.seek(8 + (0x91C * config))
sel = struct.unpack(">B", fp.read(1))[0]
if(sel & 0x02):
return 0
else:
return 1
fp.close()
def getSSID(self, config):
if(not self.getNotBlank(config)):
return None
fp = open(self.f, "rb")
fp.seek(8 + (0x91C * config) + 2021)
len = struct.unpack(">B", fp.read(1))[0]
fp.seek(8 + (0x91C * config) + 1988)
ssid = fp.read(len)
fp.close()
return ssid
def getEncryptionType(self, config):
if(not self.getNotBlank(config)):
return None
fp = open(self.f, "rb")
fp.seek(8 + (0x91C * config) + 2025)
crypt = struct.unpack(">B", fp.read(1))[0]
type = ""
if(crypt == 0):
type = "OPEN"
elif(crypt == 1):
type = "WEP"
elif(crypt == 4):
type = "WPA (TKIP)"
elif(crypt == 5):
type = "WPA2"
elif(crypt == 6):
type = "WPA (AES)"
else:
print("Invalid crypto type %02X. Valid types are: ``OPEN'', ``WEP'', ``WPA (TKIP)'', ``WPA2'', or ``WPA (AES)''\n" % crypt)
fp.close()
return None
fp.close()
return type
def getEncryptionKey(self, config):
if(not self.getNotBlank(config)):
return None
fp = open(self.f, "rb")
fp.seek(8 + (0x91C * config) + 2025)
crypt = struct.unpack(">B", fp.read(1))[0]
type = ""
if(crypt == 0):
type = "OPEN"
elif(crypt == 1):
type = "WEP"
elif(crypt == 4):
type = "WPA (TKIP)"
elif(crypt == 5):
type = "WPA2"
elif(crypt == 6):
type = "WPA (AES)"
else:
print("Invalid crypto type %02X. Valid types are: ``OPEN'', ``WEP'', ``WPA (TKIP)'', ``WPA2'', or ``WPA (AES)''\n" % crypt)
fp.close()
return None
if(crypt != "\x00"):
fp.seek(8 + (0x91C * config) + 2029)
keylen = struct.unpack(">B", fp.read(1))[0]
fp.seek(8 + (0x91C * config) + 2032)
key = fp.read(keylen)
fp.close()
return key
fp.close()
return None
def clearConfig(self, config):
fp = open(self.f, "rb+")
fp.seek(8 + (0x91C * config))
sel = struct.unpack(">B", fp.read(1))[0]
sel &= 0xDF
fp.seek(8 + (0x91C * config))
fp.write(struct.pack(">B", sel))
fp.close()
def setNotBlank(self, config):
fp = open(self.f, "rb+")
fp.seek(8 + (0x91C * config))
sel = struct.unpack(">B", fp.read(1))[0]
sel |= 0x20
fp.seek(8 + (0x91C * config))
fp.write(struct.pack(">B", sel))
fp.close()
def setIPType(self, config, static):
fp = open(self.f, "rb+")
fp.seek(8 + (0x91C * config))
sel = struct.unpack(">B", fp.read(1))[0]
if(not static):
sel |= 0x04
else:
sel &= 0xFB
fp.seek(8 + (0x91C * config))
fp.write(struct.pack(">B", sel))
fp.close()
self.setNotBlank(config)
def setWireType(self, config, wired):
fp = open(self.f, "rb+")
fp.seek(8 + (0x91C * config))
sel = struct.unpack(">B", fp.read(1))[0]
if(not wired):
sel |= 0x02
else:
sel &= 0xFD
fp.seek(8 + (0x91C * config))
fp.write(struct.pack(">B", sel))
fp.close()
self.setNotBlank(config)
def setSSID(self, config, ssid):
fp = open(self.f, "rb+")
fp.seek(8 + (0x91C * config) + 1988)
fp.write(ssid)
fp.seek(8 + (0x91C * config) + 2021)
fp.write(a2b_hex("%02X" % len(ssid)))
fp.close()
self.setNotBlank(config)
def setEncryption(self, config, crypt, key):
fp = open(self.f, "rb+")
fp.seek(8 + (0x91C * config) + 2025)
if(crypt == "OPEN"):
fp.write("\x00")
elif(crypt == "WEP"):
fp.write("\x01")
elif(crypt == "WPA (TKIP)"):
fp.write("\x04")
elif(crypt == "WPA2"):
fp.write("\x05")
elif(crypt == "WPA (AES)"):
fp.write("\x06")
else:
print("Invalid crypto type. Valid types are: ``OPEN'', ``WEP'', ``WPA (TKIP)'', ``WPA2'', or ``WPA (AES)''\n")
fp.close()
return
if(crypt != "OPEN"):
fp.seek(8 + (0x91C * config) + 2029)
fp.write(a2b_hex("%02X" % len(key)))
fp.seek(8 + (0x91C * config) + 2032)
fp.write(key)
fp.close()
self.setNotBlank(config)
def selectConfig(self, config):
fp = open(self.f, "rb+")
fp.seek(8 + (0x91C * 0))
sel = struct.unpack(">B", fp.read(1))[0]
if(config == 0):
sel |= 0x80
else:
sel &= 0x7F
fp.seek(8 + (0x91C * 0))
fp.write(struct.pack(">B", sel))
fp.seek(8 + (0x91C * 1))
sel = struct.unpack(">B", fp.read(1))[0]
if(config == 1):
sel |= 0x80
else:
sel &= 0x7F
fp.seek(8 + (0x91C * 1))
fp.write(struct.pack(">B", sel))
fp.seek(8 + (0x91C * 2))
sel = struct.unpack(">B", fp.read(1))[0]
if(config == 2):
sel |= 0x80
else:
sel &= 0x7F
fp.seek(8 + (0x91C * 2))
fp.write(struct.pack(">B", sel))
self.setNotBlank(config)
fp.close()
class ContentMap:
"""This class performs all content.map related actions. Has functions to add contents, and find contents by hash.
The ``map'' parameter is the location of the content.map file."""
def __init__(self, map):
self.f = map
if(not os.path.isfile(map)):
open(map, "wb").close()
def contentByHash(self, hash):
"""When passed a sha1 hash (string of length 20), this will return the filename of the shared content (/shared1/%08x.app, no NAND prefix) specified by the hash in content.map. Note that if the content is not found, it will return False - not an empty string."""
cmfp = open(self.f, "rb")
cmdict = {}
num = len(cmfp.read()) / 28
cmfp.seek(0)
for z in range(num):
name = cmfp.read(8)
hash = cmfp.read(20)
cmdict[name] = hash
for key, value in cmdict.iteritems():
if(value == hash):
return "/shared1/%s.app" % key
return False #not found
def addContentToMap(self, contentid, hash):
"""Adds a content to the content.map file for the contentid and hash.
Returns the content id."""
cmfp = open(self.f, "rb")
cmdict = {}
num = len(cmfp.read()) / 28
cmfp.seek(0)
for z in range(num):
name = cmfp.read(8)
hash = cmfp.read(20)
cmdict[name] = hash
cmdict["%08x" % contentid] = hash
cmfp.close()
cmfp = open(self.f, "wb")
for key, value in cmdict.iteritems():
cmfp.write(key)
cmfp.write(value)
cmfp.close()
return contentid
def addHashToMap(self, hash):
"""Adds a content to the content.map file for the hash (uses next unavailable content id)
Returns the content id."""
cmfp = open(self.f, "rb")
cmdict = {}
cnt = 0
num = len(cmfp.read()) / 28
cmfp.seek(0)
for z in range(num):
name = cmfp.read(8)
hasho = cmfp.read(20)
cmdict[name] = hasho
cnt += 1
cmdict["%08x" % cnt] = hash
cmfp.close()
cmfp = open(self.f, "wb")
for key, value in cmdict.iteritems():
cmfp.write(key)
cmfp.write(value)
cmfp.close()
return cnt
def contentCount(self):
cmfp = open(self.f, "rb")
cmdict = {}
cnt = 0
num = len(cmfp.read()) / 28
cmfp.seek(0)
for z in range(num):
name = cmfp.read(8)
hash = cmfp.read(20)
cmdict[name] = hash
cnt += 1
cmfp.close()
return cnt
def contentHashes(self, count):
cmfp = open(self.f, "rb")
num = len(cmfp.read()) / 28
if(num > count):
num = count
cmfp.seek(0)
hashout = ""
for z in range(num):
name = cmfp.read(8)
hashout += cmfp.read(20)
cmfp.close()
return hashout
class uidsys:
"""This class performs all uid.sys related actions. It includes functions to add titles and find titles from the uid.sys file.
The ``uid'' parameter is the location of the uid.sys file."""
class UIDSYSStruct(Struct):
__endian__ = Struct.BE
def __format__(self):
self.titleid = Struct.uint64
self.padding = Struct.uint16
self.uid = Struct.uint16
def __init__(self, uid):
self.f = uid
if(not os.path.isfile(uid)):
uidfp = open(uid, "wb")
uiddat = self.UIDSYSStruct()
uiddat.titleid = 0x0000000100000002
uiddat.padding = 0
uiddat.uid = 0x1000
uidfp.write(uiddat.pack())
uidfp.close()
if((os.path.isfile(uid)) and (len(open(uid, "rb").read()) == 0)):
uidfp = open(uid, "wb")
uiddat = self.UIDSYSStruct()
uiddat.titleid = 0x0000000100000002
uiddat.padding = 0
uiddat.uid = 0x1000
uidfp.write(uiddat.pack())
uidfp.close()
def getUIDForTitle(self, title):
uidfp = open(self.f, "rb")
uiddat = uidfp.read()
cnt = len(uiddat) / 12
uidfp.seek(0)
uidstr = self.UIDSYSStruct()
uidict = {}
for i in range(cnt):
uidstr.titleid = uidfp.read(8)
uidstr.padding = uidfp.read(2)
uidstr.uid = uidfp.read(2)
uidict[uidstr.titleid] = uidstr.uid
for key, value in uidict.iteritems():
if(hexdump(key, "") == ("%016X" % title)):
return value
return self.addTitle(title)
def getTitle(self, uid):
uidfp = open(self.f, "rb")
uiddat = uidfp.read()
cnt = len(uiddat) / 12
uidfp.seek(0)
uidstr = self.UIDSYSStruct()
uidict = {}
for i in range(cnt):
uidstr.titleid = uidfp.read(8)
uidstr.padding = uidfp.read(2)
uidstr.uid = uidfp.read(2)
uidict[uidstr.titleid] = uidstr.uid
for key, value in uidict.iteritems():
if(hexdump(value, "") == ("%04X" % uid)):
return key
return None
def addTitle(self, title):
uidfp = open(self.f, "rb")
uiddat = uidfp.read()
cnt = len(uiddat) / 12
uidfp.seek(0)
uidstr = self.UIDSYSStruct()
uidict = {}
enduid = "\x10\x01"
for i in range(cnt):
uidstr.titleid = uidfp.read(8)
uidstr.padding = uidfp.read(2)
uidstr.uid = uidfp.read(2)
if(hexdump(uidstr.titleid, "") == ("%016X" % title)):
uidfp.close()
return uidstr.uid
if(struct.unpack(">H", uidstr.uid) >= struct.unpack(">H", enduid)):
enduid = a2b_hex("%04X" % (struct.unpack(">H", uidstr.uid)[0] + 1))
uidict[uidstr.titleid] = uidstr.uid
uidict[a2b_hex("%016X" % title)] = enduid
uidfp.close()
uidfp = open(self.f, "wb")
for key, value in uidict.iteritems():
uidfp.write(key)
uidfp.write("\0\0")
uidfp.write(value)
uidfp.close()
return enduid
class iplsave:
"""This class performs all iplsave.bin related things. It includes functions to add a title to the list, remove a title based upon position or title, and move a title from one position to another."""
class IPLSAVE_Entry(Struct):
__endian__ = Struct.BE
def __format__(self):
self.type1 = Struct.uint8
self.type2 = Struct.uint8
self.unk = Struct.uint32
self.flags = Struct.uint16
self.titleid = Struct.uint64
class IPLSAVE_Header(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.filesize = Struct.uint32
self.unk = Struct.uint64
# 0x30 Entries go here.
self.unk2 = Struct.string(0x20)
self.md5 = Struct.string(0x10)
def __init__(self, f, nand = False):
self.f = f
if(not os.path.isfile(f)):
if(nand != False):
nand.newFile("/title/00000001/00000002/data/iplsave.bin", "rw----", 0x0001, 0x0000000100000002)
baseipl_h = self.IPLSAVE_Header
baseipl_ent = self.IPLSAVE_Entry
baseipl_ent.type1 = 0
baseipl_ent.type2 = 0
baseipl_ent.unk = 0
baseipl_ent.flags = 0
baseipl_ent.titleid = 0
baseipl_h.magic = "RIPL"
baseipl_h.filesize = 0x340
baseipl_h.unk = 0x0000000200000000
baseipl_h.unk2 = "\0" * 0x20
fp = open(f, "wb")
fp.write(baseipl_h.magic)
fp.write(a2b_hex("%08X" % baseipl_h.filesize))
fp.write(a2b_hex("%016X" % baseipl_h.unk))
i = 0
for i in range(0x30):
fp.write(a2b_hex("%02X" % baseipl_ent.type1))
fp.write(a2b_hex("%02X" % baseipl_ent.type2))
fp.write(a2b_hex("%08X" % baseipl_ent.unk))
fp.write(a2b_hex("%04X" % baseipl_ent.flags))
fp.write(a2b_hex("%016X" % baseipl_ent.titleid))
fp.write(baseipl_h.unk2)
fp.close()
self.updateMD5()
def updateMD5(self):
"""Updates the MD5 hash in the iplsave.bin file. Used by other functions here."""
fp = open(self.f, "rb")
data = fp.read()
fp.close()
md5 = Crypto().createMD5Hash(data)
fp = open(self.f, "wb")
fp.write(data)
fp.write(md5)
fp.close()
def slotUsed(self, x, y, page):
"""Returns whether or not the slot at (x,y) on page ``page'' is used."""
if((x + (y * 4) + (page * 12)) >= 0x30):
print "Too far!"
return None
fp = open(self.f, "rb")
data = fp.read()
fp.seek(16 + ((x + (y * 4) + (page * 12))) * 16)
baseipl_ent = self.IPLSAVE_Entry
baseipl_ent.type1 = fp.read(1)
baseipl_ent.type2 = fp.read(1)
baseipl_ent.unk = fp.read(4)
baseipl_ent.flags = fp.read(2)
baseipl_ent.titleid = fp.read(8)
fp.close()
if(baseipl_ent.type1 == "\0"):
return 0
return baseipl_ent.titleid
def addTitleBase(self, x, y, page, tid, movable, type, overwrite, clear, isdisc):
"""A base addTitle function that is used by others. Don't use this."""
if((x + (y * 4) + (page * 12)) >= 0x30):
print "Too far!"
return None
fp = open(self.f, "rb")
data = fp.read()
fp.seek(16 + ((x + (y * 4) + (page * 12))) * 16)
baseipl_ent = self.IPLSAVE_Entry
baseipl_ent.type1 = fp.read(1)
fp.close()
if((self.slotUsed(x, y, page)) and (not overwrite)):
return self.addTitleBase(x + 1, y, page, tid, movable, type, overwrite, clear, isdisc)
fp = open(self.f, "wb")
fp.write(data)
fp.seek(16 + ((x + (y * 4) + (page * 12))) * 16)
if((not clear) and (not isdisc)):
baseipl_ent.type1 = 3
baseipl_ent.type2 = type
baseipl_ent.unk = 0
baseipl_ent.flags = (movable ^ 1) + 0x0E
baseipl_ent.titleid = tid
if((clear) and (not isdisc)):
baseipl_ent.type1 = 0
baseipl_ent.type2 = 0
baseipl_ent.unk = 0
baseipl_ent.flags = 0
baseipl_ent.titleid = 0
if(isdisc):
baseipl_ent.type1 = 1
baseipl_ent.type2 = 1
baseipl_ent.unk = 0
baseipl_ent.flags = (movable ^ 1) + 0x0E
baseipl_ent.titleid = 0
fp.write(a2b_hex("%02X" % baseipl_ent.type1))
fp.write(a2b_hex("%02X" % baseipl_ent.type2))
fp.write(a2b_hex("%08X" % baseipl_ent.unk))
fp.write(a2b_hex("%04X" % baseipl_ent.flags))
fp.write(a2b_hex("%016X" % baseipl_ent.titleid))
fp.close()
self.updateMD5()
return (x + (y * 4) + (page * 12))
def addTitle(self, x, y, page, tid, movable, type):
"""Adds a title with title ID ``tid'' at location (x,y) on page ``page''. ``movable'' specifies whether the title is movable, and ``type'' specifies the type of title (00 for most titles.)"""
return self.addTitleBase(x, y, page, tid, movable, type, 0, 0, 0)
def addDisc(self, x, y, page, movable):
"""Adds the Disc Channel at location (x,y) on page ``page''. ``movable'' specifies whether it can be moved."""
return self.addTitleBase(x, y, page, 0, movable, 0, 0, 0, 1)
def deletePosition(self, x, y, page):
"""Deletes the title at (x,y) on page ``page''"""
return self.addTitleBase(x, y, page, 0, 0, 0, 1, 1, 0)
def deleteTitle(self, tid):
"""Deletes the title with title ID ``tid''"""
fp = open(self.f, "rb")
baseipl_ent = self.IPLSAVE_Entry
for i in range(0x30):
fp.seek(16 + (i * 16))
baseipl_ent.type1 = fp.read(1)
baseipl_ent.type2 = fp.read(1)
baseipl_ent.unk = fp.read(4)
baseipl_ent.flags = fp.read(2)
baseipl_ent.titleid = fp.read(8)
if(baseipl_ent.titleid == a2b_hex("%016X" % tid)):
self.deletePosition(i, 0, 0)
fp.close()
def moveTitle(self, x1, y1, page1, x2, y2, page2):
"""Moves a title from (x1,y1) on page ``page1'' to (x2,y2) on page ``page2''"""
fp = open(self.f, "rb")
baseipl_ent = self.IPLSAVE_Entry
fp.seek(16 + ((x1 + (y1 * 4) + (page1 * 12)) * 16))
baseipl_ent.type1 = fp.read(1)
baseipl_ent.type2 = fp.read(1)
baseipl_ent.unk = fp.read(4)
baseipl_ent.flags = fp.read(2)
baseipl_ent.titleid = fp.read(8)
fp.close()
self.deletePosition(x1, y1, page1)
return self.addTitle(x2, y2, page2, baseipl_ent.titleid, (baseipl_ent.flags - 0xE) ^ 1, baseipl_ent.type2)

112
WiiPy/headers.py Normal file
View File

@ -0,0 +1,112 @@
from common import *
class IMD5(WiiHeader):
"""This class can add and remove IMD5 headers to files. The parameter f is the file to use for the addition or removal of the header. IMD5 headers are found in banner.bin, icon.bin, and sound.bin."""
class IMD5Header(Struct):
__endian__ = Struct.BE
def __format__(self):
self.tag = Struct.string(4)
self.size = Struct.uint32
self.zeroes = Struct.uint8[8]
self.crypto = Struct.string(16)
def add(self):
data = self.data
imd5 = self.IMD5Header()
imd5.tag = "IMD5"
imd5.size = len(data)
for i in range(8):
imd5.zeroes[i] = 0x00
imd5.crypto = str(Crypto().createMD5Hash(data))
data = imd5.pack() + data
return data
def remove(self):
"""This will remove an IMD5 header from the file specified in f, if one exists. If there is no IMD5 header, it will output the file as it is. It will output in the parameter fn if available, otherwise it will overwrite the source. Returns the output filename."""
data = self.data
imd5 = self.IMD5Header()
if(data[:4] != "IMD5"):
if(fn != ""):
open(fn, "wb").write(data)
return fn
else:
return self.f
data = data[len(imd5):]
return data
class IMET(WiiHeader):
"""IMET headers are found in Opening.bnr and 0000000.app files. They contain the channel titles and more metadata about channels. They are in two different formats with different amounts of padding before the start of the IMET header. This class suports both.
The parameter f is used to specify the input file name."""
class IMETHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.zeroes = Struct.uint8[128]
self.tag = Struct.string(4)
self.unk = Struct.uint64
self.sizes = Struct.uint32[3] #icon, banner, sound
self.unk2 = Struct.uint32
self.names = Struct.string(84, encoding = "utf-16-be", stripNulls = True)[7]
self.zeroes2 = Struct.uint8[840]
self.hash = Struct.string(16)
def add(self, iconsz, bannersz, soundsz, name = "", langs = [], fn = ""):
"""This function adds an IMET header to the file specified with f in the initializer. The file will be output to fn if it is not empty, otherwise it will overwrite the input file. You must specify the size of banner.bin in bannersz, and respectivly for iconsz and soundsz. langs is an optional arguement that is a list of different langauge channel titles. name is the english name that is copied everywhere in langs that there is an empty string. Returns the output filename."""
data = self.data
imet = self.IMETHeader()
for i in imet.zeroes:
imet.zeroes[i] = 0x00
imet.tag = "IMET"
imet.unk = 0x0000060000000003
imet.sizes[0] = iconsz
imet.sizes[1] = bannersz
imet.sizes[2] = soundsz
imet.unk2 = 0
for i in range(len(imet.names)):
if(len(langs) > 0 and langs[i] != ""):
imet.names[i] = langs[i]
else:
imet.names[i] = name
for i in imet.zeroes2:
imet.zeroes2[i] = 0x00
imet.hash = "\x00" * 16
tmp = imet.pack()
imet.hash = Crypto().createMD5Hash(tmp[0x40:0x640]) #0x00 or 0x40?
data = imet.pack() + data
return data
def remove(self):
data = self.data
if(data[0x80:0x84] == "IMET"):
data = data[0x640:]
elif(data[0x40:0x44] == "IMET"):
data = data[0x640:]
return data
def getTitle(self):
imet = self.IMETHeader()
data = self.data
if(data[0x40:0x44] == "IMET"):
pass
elif(data[0x80:0x84] == "IMET"):
data = data[0x40:]
else:
raise ValueError("No IMET header found!")
imet.unpack(data[:len(imet)])
name = imet.names[1]
topop = []
for i in range(len(name)):
if(name[i] == "\x00"):
topop.append(i)
name = list(name)
popped = 0 #don't ask me why I did this
for pop in topop:
name.pop(pop - popped)
popped += 1
name = ''.join(name)
return name

802
WiiPy/image.py Normal file
View File

@ -0,0 +1,802 @@
#!/usr/bin/env python
from common import *
import wx
def flatten(myTuple):
if (len(myTuple) == 4):
return myTuple[0] << 0 | myTuple[1] << 8 | myTuple[2] << 16 | myTuple[3] << 24
else:
return myTuple[0] << 0 | myTuple[1] << 8 | myTuple[2] << 16 | 0xff << 24
def round_up(x, n):
left = x % n
return x + left
def avg(w0, w1, c0, c1):
a0 = c0 >> 11
a1 = c1 >> 11
a = (w0*a0 + w1*a1) / (w0 + w1)
c = (a << 11) & 0xffff
a0 = (c0 >> 5) & 63
a1 = (c1 >> 5) & 63
a = (w0*a0 + w1*a1) / (w0 + w1)
c = c | ((a << 5) & 0xffff)
a0 = c0 & 31
a1 = c1 & 31
a = (w0*a0 + w1*a1) / (w0 + w1)
c = c | a
return c
class TPL():
"""This is the class to generate TPL texutres from PNG images, and to convert TPL textures to PNG images. The parameter file specifies the filename of the source, either a PNG image or a TPL image.
Currently supported are the following formats to convert from TPL (all formats): RGBA8, RGB565, RGB5A3, I4, IA4, I8, IA8, CI4, CI8, CMP, CI14X2.
Currently supported to convert to TPL: I4, I8, IA4, IA8, RBG565, RBGA8, RGB5A3. Currently not supported are CI4, CI8, CMP, CI14X2."""
class TPLHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.uint32
self.ntextures = Struct.uint32
self.header_size = Struct.uint32
class TPLTexture(Struct):
__endian__ = Struct.BE
def __format__(self):
self.header_offset = Struct.uint32
self.palette_offset = Struct.uint32
class TPLTextureHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.height = Struct.uint16
self.width = Struct.uint16
self.format = Struct.uint32
self.data_off = Struct.uint32
self.wrap = Struct.uint32[2]
self.filter = Struct.uint32[2]
self.lod_bias = Struct.float
self.edge_lod = Struct.uint8
self.min_lod = Struct.uint8
self.max_lod = Struct.uint8
self.unpacked = Struct.uint8
class TPLPaletteHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.nitems = Struct.uint16
self.unpacked = Struct.uint8
self.pad = Struct.uint8
self.format = Struct.uint32
self.offset = Struct.uint32
def __init__(self, file):
if(not ("\x00" in file) and os.path.isfile(file)):
self.file = file
self.data = None
else:
self.file = None
self.data = file
def toTPL(self, outfile, (width, height) = (None, None), format = "RGBA8"): #single texture only
"""This converts an image into a TPL. The image is specified as the file parameter to the class initializer, while the output filename is specified here as the parameter outfile. Width and height are optional parameters and specify the size to resize the image to, if needed. Returns the output filename.
This only can create TPL images with a single texture."""
head = self.TPLHeader()
head.magic = 0x0020AF30
head.ntextures = 1
head.header_size = 0x0C
tex = self.TPLTexture()
tex.header_offset = 0x14
tex.pallete_offset = 0
img = Image.open(self.file)
theWidth, theHeight = img.size
if(width != None and height != None and (width != theWidth or height != theHeight)):
img = img.resize((width, height), Image.ANTIALIAS)
w, h = img.size
texhead = self.TPLTextureHeader()
texhead.height = h
texhead.width = w
if format == "I4":
texhead.format = 0
tpldata = self.toI4((w, h), img)
elif format == "I8":
texhead.format = 1
tpldata = self.toI8((w, h), img)
elif format == "IA4":
texhead.format = 2
tpldata = self.toIA4((w, h), img)
elif format == "IA8":
texhead.format = 3
tpldata = self.toIA8((w, h), img)
elif format == "RGB565":
texhead.format = 4
tpldata = self.toRGB565((w, h), img)
elif format == "RGB5A3":
texhead.format = 5
tpldata = self.toRGB5A3((w, h), img)
elif format == "RGBA8":
texhead.format = 6
tpldata = self.toRGBA8((w, h), img)
elif format == "CI4":
texhead.format = 8
''' ADD toCI4 '''
raise Exception("toCI4 not done")
#tpldata = self.toCI4((w, h), img)
elif format == "CI8":
texhead.format = 9
''' ADD toCI8 '''
raise Exception("toCI8 not done")
#tpldata = self.toCI8((w, h), img)
elif format == "CI14X2":
texhead.format = 10
''' ADD toCI14X2 '''
raise Exception("toCI14X2 not done")
#tpldata = self.toCI14X2((w, h), img)
elif format == "CMP":
texhead.format = 14
''' ADD toCMP '''
raise Exception("toCMP not done")
#tpldata = self.toCMP((w, h), img)
texhead.data_off = 0x14 + len(texhead)
texhead.wrap = [0, 0]
texhead.filter = [1, 1]
texhead.lod_bias = 0
texhead.edge_lod = 0
texhead.min_lod = 0
texhead.max_lod = 0
texhead.unpacked = 0
f = open(outfile, "wb")
f.write(head.pack())
f.write(tex.pack())
f.write(texhead.pack())
if format == "I4":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) / 2) + "B", *tpldata))
if format == "I8":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 1) + "B", *tpldata))
if format == "IA4":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 1) + "B", *tpldata))
if format == "IA8":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 1) + "H", *tpldata))
if format == "RGB565":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 1) + "H", *tpldata))
if format == "RGB5A3":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 1) + "H", *tpldata))
if format == "RGBA8":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 4) + "B", *tpldata))
if format == "CI4":
''' ADD toCI4 '''
#f.write(struct.pack(">"+ str(align(w,4) * align(h,4) * 4) + "B", *tpldata))
if format == "CI8":
''' ADD toCI8 '''
#f.write(struct.pack(">"+ str(align(w,4) * align(h,4) * 4) + "B", *tpldata))
if format == "CI14X2":
''' ADD toCI14X2 '''
#f.write(struct.pack(">"+ str(align(w,4) * align(h,4) * 4) + "B", *tpldata))
if format == "CMP":
''' ADD toCMP '''
#f.write(struct.pack(">"+ str(align(w,4) * align(h,4) * 4) + "B", *tpldata))
f.close()
return outfile
def toI4(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4) / 2)]
outp = 0
inp = list(img.getdata())
for y1 in range(0, h, 8):
for x1 in range(0, w, 8):
for y in range(y1, y1+8, 1):
for x in range(x1, x1+8, 2):
if x>=w or y>=h:
newpixel = 0
else:
rgba = flatten(inp[x+y*w])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
i1 = ((r + g + b) / 3) & 0xff
rgba = flatten(inp[x+1+y*w])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
i2 = ((r + g + b) / 3) & 0xff
newpixel = (((i1 * 15) / 255) << 4)
newpixel |= (((i2 * 15) / 255) & 0xf)
out[outp] = newpixel
outp += 1
return out
def toI8(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4))]
outp = 0
inp = list(img.getdata())
for y1 in range(0, h, 4):
for x1 in range(0, w, 8):
for y in range(y1, y1+4, 1):
for x in range(x1, x1+8, 1):
rgba = flatten(inp[x + (y * w)])
if x>= w or y>=h:
i1 = 0
else:
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
i1 = ((r + g + b) / 3) & 0xff
out[outp] = i1
outp += 1
return out
def toIA4(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4))]
outp = 0
inp = list(img.getdata())
for y1 in range(0, h, 4):
for x1 in range(0, w, 8):
for y in range(y1, y1+4, 1):
for x in range(x1, x1+8, 1):
if x>=w or y>=h:
newpixel = 0
else:
rgba = flatten(inp[x + (y * w)])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
i1 = ((r + g + b) / 3) & 0xff
a1 = (rgba >> 24) & 0xff
newpixel = (((i1 * 15) / 255) & 0xf)
newpixel = newpixel | (((a1 * 15) / 255) << 4)
out[outp] = newpixel
outp += 1
return out
def toIA8(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4))]
outp = 0
inp = list(img.getdata())
for y1 in range(0, h, 4):
for x1 in range(0, w, 4):
for y in range(y1, y1+4, 1):
for x in range(x1, x1+4, 1):
if x>=w or y>=h:
newpixel = 0
else:
rgba = flatten(inp[x + (y * w)])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
i1 = ((r + g + b) / 3) & 0xff
a1 = (rgba >> 24) & 0xff
newpixel = i1 << 8
newpixel = newpixel | a1
out[outp] = newpixel
outp += 1
return out
def toRGB565(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4))]
outp = 0
inp = img.getdata()
for y1 in range(0, h, 4):
for x1 in range(0, w, 4):
for y in range(y1, y1+4, 1):
for x in range(x1, x1+4, 1):
newpixel = 0
if x>=w or y>=h:
newpixel = 0
else:
rgba = flatten(inp[x+y*w])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
newpixel = ((b >>3) << 11) | ((g >>2) << 5) | ((r >>3) << 0)
out[outp] = newpixel
outp += 1
return out
def toRGB5A3(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4))]
outp = 0
inp = list(img.getdata())
for y1 in range(0, h, 4):
for x1 in range(0, w, 4):
for y in range(y1, y1+4, 1):
for x in range(x1, x1+4, 1):
newpixel = 0
if x>=w or y>=h:
newpixel = 0
else:
rgba = flatten(inp[x + (y * h)])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
a = (rgba >> 24) & 0xff
if (a <= 0xda):
newpixel &= ~(1 << 15)
r = ((r * 15) / 255) & 0xf
g = ((g * 15) / 255) & 0xf
b = ((b * 15) / 255) & 0xf
a = ((a * 7) / 255) & 0x7
#newpixel |= r << 12
#newpixel |= g << 8
#newpixel |= b << 4
#newpixel |= a << 0
newpixel |= a << 12
newpixel |= b << 8
newpixel |= g << 4
newpixel |= r << 0
else:
newpixel |= (1 << 15)
r = ((r * 31) / 255) & 0x1f
g = ((g * 31) / 255) & 0x1f
b = ((b * 31) / 255) & 0x1f
newpixel |= b << 10
newpixel |= g << 5
newpixel |= r << 0
out[outp] = newpixel
outp += 1
return out
def toRGBA8(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4) * 4)]
inp = list(img.getdata())
iv = 0
z = 0
lr = [0 for i in range(32)]
lg = [0 for i in range(32)]
lb = [0 for i in range(32)]
la = [0 for i in range(32)]
for y1 in range(0, h, 4):
for x1 in range(0, w, 4):
for y in range(y1, y1 + 4, 1):
for x in range(x1, x1 + 4, 1):
if(y >= h or x >= w):
lr[z] = 0
lg[z] = 0
lb[z] = 0
la[z] = 0
else:
rgba = flatten(inp[x + (y * w)])
lr[z] = (rgba >> 0) & 0xff
lg[z] = (rgba >> 8) & 0xff
lb[z] = (rgba >> 16) & 0xff
la[z] = (rgba >> 24) & 0xff
z += 1
if(z == 16):
for i in range(16):
out[iv] = la[i] & 0xff
iv += 1
out[iv] = lr[i] & 0xff
iv += 1
for i in range(16):
out[iv] = lg[i] & 0xff
iv += 1
out[iv] = lb[i] & 0xff
iv += 1
z = 0
return out
def toImage(self, outfile):
"""This converts a TPL texture to a PNG image. You specify the input TPL filename in the initializer, and you specify the output filename in the outfile parameter to this method. Returns the output filename.
This only supports single textured TPL images."""
if(self.file):
data = open(self.file, "rb").read()
else:
data = self.data
header = self.TPLHeader()
textures = []
pos = 0
header.unpack(data[pos:pos + len(header)])
pos += len(header)
palette_offsets = []
for i in range(header.ntextures):
tmp = self.TPLTexture()
tmp.unpack(data[pos:pos + len(tmp)])
textures.append(tmp)
pos += len(tmp)
if(tmp.palette_offset > 0):
palette_offsets.append(tmp.palette_offset)
if(header.ntextures > 1):
raise ValueError("Only one texture supported. Don't touch me!")
for i in range(header.ntextures):
head = textures[i]
tex = self.TPLTextureHeader()
tex.unpack(data[head.header_offset:head.header_offset + len(tex)])
w = tex.width
h = tex.height
print tex.format
if(tex.format == 0): #I4, 4-bit
tpldata = struct.unpack(">" + str((w * h) / 2) + "B", data[tex.data_off:tex.data_off + ((w * h) / 2)])
rgbdata = self.I4((w, h), tpldata)
elif(tex.format == 1): #I8, 8-bit
tpldata = struct.unpack(">" + str(w * h) + "B", data[tex.data_off:tex.data_off + (w * h * 1)])
rgbdata = self.I8((w, h), tpldata)
elif(tex.format == 2): #IA4, 8-bit
tpldata = struct.unpack(">" + str(w * h) + "B", data[tex.data_off:tex.data_off + (w * h * 1)])
rgbdata = self.IA4((w, h), tpldata)
elif(tex.format == 4): #RGB565, 16-bit
tpldata = data[tex.data_off:]
rgbdata = self.RGB565((w, h), tpldata)
elif(tex.format == 5): #RGB5A3, 16-bit
tpldata = data[tex.data_off:]
rgbdata = self.RGB5A3((w, h), tpldata)
elif(tex.format == 3): #IA8, 16-bit
tpldata = data[tex.data_off:]
rgbdata = self.IA8((w, h), tpldata)
elif(tex.format == 6): #RGBA8, 32-bit, but for easyness's sake lets do it with 16-bit
tpldata = data[tex.data_off:]
rgbdata = self.RGBA8((w, h), tpldata)
elif(tex.format == 8 or tex.format == 9 or tex.format == 10):
palhead = self.TPLPaletteHeader()
offs = palette_offsets.pop(0)
palhead.unpack(data[offs:offs + len(palhead)])
tpldata = struct.unpack(">" + str(palhead.nitems) + "H", data[palhead.offset:palhead.offset + (palhead.nitems * 2)])
if(palhead.format == 0):
palette_data = self.IA8((palhead.nitems, 1), tpldata)[0]
elif(palhead.format == 1):
palette_data = self.RGB565((palhead.nitems, 1), tpldata)[0]
elif(palhead.format == 2):
palette_data = self.RGB5A3((palhead.nitems, 1), tpldata)[0]
paldata = []
for i in range(0, palhead.nitems * 4, 4):
tmp = 0
tmp |= palette_data[i + 0] << 24
tmp |= palette_data[i + 1] << 16
tmp |= palette_data[i + 2] << 8
tmp |= palette_data[i + 3] << 0
paldata.append(tmp)
if(tex.format == 8):
tpldata = struct.unpack(">" + str((w * h) / 2) + "B", data[tex.data_off:tex.data_off + ((w * h) / 2)])
rgbdata = self.CI4((w, h), tpldata, paldata)
if(tex.format == 9):
tpldata = struct.unpack(">" + str(w * h) + "B", data[tex.data_off:tex.data_off + (w * h * 1)])
rgbdata = self.CI8((w, h), tpldata, paldata)
if(tex.format == 10):
tpldata = struct.unpack(">" + str(w * h) + "H", data[tex.data_off:tex.data_off + (w * h * 2)])
rgbdata = self.CI14X2((w, h), tpldata, paldata)
elif(tex.format == 14):
tpldata = ''.join(data[tex.data_off:])
rgbdata = self.CMP((w, h), tpldata)
else:
raise TypeError("Unsupported TPL Format: " + str(tex.format))
output = Image.fromstring("RGBA", (w, h), rgbdata)
ext = outfile[outfile.rfind(".")+1:]
output.save(outfile, ext)
return outfile
def getSizes(self):
"""This returns a tuple containing the width and height of the TPL image filename in the class initializer. Will only return the size of single textured TPL images."""
data = open(self.file, "rb").read()
header = self.TPLHeader()
textures = []
pos = 0
header.unpack(data[pos:pos + len(header)])
pos += len(header)
for i in range(header.ntextures):
tmp = self.TPLTexture()
tmp.unpack(data[pos:pos + len(tmp)])
textures.append(tmp)
pos += len(tmp)
for i in range(header.ntextures):
head = textures[i]
tex = self.TPLTextureHeader()
tex.unpack(data[head.header_offset:head.header_offset + len(tex)])
w = tex.width
h = tex.height
return (w, h)
def toScreen(self): #single texture only
"""This will draw a simple window with the TPL image displayed on it. It uses WxPython for the window creation and management. The window has a minimum width and height of 300 x 200. Does not return a value.
Again, only a single texture is supported."""
import wx
class imp(wx.Dialog):
def __init__(self, title, im):
w = img.GetWidth()
h = img.GetHeight()
wx.Dialog.__init__(self, None, -1, title, size = (max(w, 300), max(h, 200)))
wx.StaticBitmap(self, -1, im, ( ((max(w, 300) - w) / 2), ((max(h, 200) - h) / 2) ), (w, h))
self.toImage("tmp.png")
img = wx.Image("tmp.png", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
w = img.GetWidth()
h = img.GetHeight()
dialog = imp("TPL (" + str(w) + ", " + str(h) + ")", img)
dialog.ShowModal()
dialog.Destroy()
os.unlink("tmp.png")
def RGBA8(self, (x, y), data):
out = [0 for i in range(x * y)]
inp = 0
for i in xrange(0, y, 4):
for j in xrange(0, x, 4):
for k in xrange(2):
for l in xrange(i, i + 4, 1):
for m in xrange(j, j + 4, 1):
texel = Struct.uint16(data[inp * 2:inp * 2 + 2], endian = '>')
inp += 1
if (m >= x) or (l >= y):
continue
if k == 0:
a = (texel >> 8) & 0xff
r = (texel >> 0) & 0xff
out[m + (l * x)] |= ((r << 0) | (a << 24))
else:
g = (texel >> 8) & 0xff
b = (texel >> 0) & 0xff
out[m + (l * x)] |= ((g << 8) | (b << 16))
return ''.join(Struct.uint32(p) for p in out)
def RGB5A3(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 4):
for y1 in range(y, y + 4):
for x1 in range(x, x + 4):
if(y1 >= h or x1 >= w):
continue
pixel = Struct.uint16(jar[i * 2:i * 2 + 2], endian='>')
i += 1
if(pixel & (1 << 15)): #RGB555
b = (((pixel >> 10) & 0x1F) * 255) / 31
g = (((pixel >> 5) & 0x1F) * 255) / 31
r = (((pixel >> 0) & 0x1F) * 255) / 31
a = 255
else: #RGB4A3
a = (((pixel >> 12) & 0x07) * 255) / 7
b = (((pixel >> 8) & 0x0F) * 255) / 15
g = (((pixel >> 4) & 0x0F) * 255) / 15
r = (((pixel >> 0) & 0x0F) * 255)/ 15
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[(y1 * w) + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def RGB565(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 4):
for y1 in range(y, y + 4):
for x1 in range(x, x + 4):
if(y1 >= h or x1 >= w):
continue
pixel = Struct.uint16(jar[i * 2:i * 2 + 2], endian='>')
i += 1
b = (((pixel >> 11) & 0x1F) << 3) & 0xff
g = (((pixel >> 5) & 0x3F) << 2) & 0xff
r = (((pixel >> 0) & 0x1F) << 3) & 0xff
a = 255
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def I4(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 8):
for x in range(0, w, 8):
for y1 in range(y, y + 8):
for x1 in range(x, x + 8, 2):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
r = (pixel >> 4) * 255 / 15
g = (pixel >> 4) * 255 / 15
b = (pixel >> 4) * 255 / 15
a = (pixel >> 4) * 255 / 15
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = (pixel & 0x0F) * 255 / 15
g = (pixel & 0x0F) * 255 / 15
b = (pixel & 0x0F) * 255 / 15
a = (pixel & 0x0F) * 255 / 15
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1 + 1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def IA4(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 8):
for y1 in range(y, y + 4):
for x1 in range(x, x + 8):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = ((pixel & 0x0F) * 255 / 15) & 0xff
g = ((pixel & 0x0F) * 255 / 15) & 0xff
b = ((pixel & 0x0F) * 255 / 15) & 0xff
a = (((pixel >> 4) * 255) / 15) & 0xff
rgba = ( r<< 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def I8(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 8):
for y1 in range(y, y + 4):
for x1 in range(x, x + 8):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = pixel
g = pixel
b = pixel
a = 255
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def IA8(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 4):
for y1 in range(y, y + 4):
for x1 in range(x, x + 4):
if(y1 >= h or x1 >= w):
continue
pixel = Struct.uint16(jar[i * 2:i * 2 + 2], endian='>')
i += 1
r = (pixel >> 8) & 0xff
g = (pixel >> 8) & 0xff
b = (pixel >> 8) & 0xff
a = pixel & 0xff
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def CI4(self, (w, h), jar, pal):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 8):
for x in range(0, w, 8):
for y1 in range(y, y + 8):
for x1 in range(x, x + 8, 2):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
r = (pal[pixel] & 0xFF000000) >> 24
g = (pal[pixel] & 0x00FF0000) >> 16
b = (pal[pixel] & 0x0000FF00) >> 8
a = (pal[pixel] & 0x000000FF) >> 0
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = (pal[pixel] & 0xFF000000) >> 24
g = (pal[pixel] & 0x00FF0000) >> 16
b = (pal[pixel] & 0x0000FF00) >> 8
a = (pal[pixel] & 0x000000FF) >> 0
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1 + 1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def CI8(self, (w, h), jar, pal):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 8):
for y1 in range(y, y + 4):
for x1 in range(x, x + 8):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = (pal[pixel] & 0xFF000000) >> 24
g = (pal[pixel] & 0x00FF0000) >> 16
b = (pal[pixel] & 0x0000FF00) >> 8
a = (pal[pixel] & 0x000000FF) >> 0
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def CMP(self, (w, h), data):
temp = [0 for i in range(w * h)]
pix = [ 0 , 0 , 0 ]
c = [ 0 , 0 , 0 , 0 ]
outp = 0
for y in xrange(h):
for x in xrange(w):
ww = round_up(w, 8)
x0 = x & 0x03
x1 = (x >> 2) & 0x01
x2 = x >> 3
y0 = y & 0x03
y1 = (y >> 2) & 0x01
y2 = y >> 3
off = (8 * x1) + (16 * y1) + (32 * x2) + (4 * ww * y2)
c[0] = Struct.uint16(data[off + 0:off + 2], endian='>')
c[1] = Struct.uint16(data[off + 2:off + 4], endian='>')
if(c[0] > c[1]):
c[2] = avg(2, 1, c[0], c[1])
c[3] = avg(1, 2, c[0], c[1])
else:
c[2] = avg(1, 1, c[0], c[1])
c[3] = 0
px = Struct.uint32(data[off+4:off + 8], endian='>')
ix = x0 + ( 4 * y0 )
raw = c[(px >> (30 - (2 * ix))) & 0x03]
pix[0] = (raw >> 8) & 0xf8
pix[1] = (raw >> 3) & 0xf8
pix[2] = (raw << 3) & 0xf8
temp[outp] = (pix[0] <<0) | (pix[1] << 8) | (pix[2] << 16) | (255 << 24)
outp += 1
return ''.join(Struct.uint32(p) for p in temp)
def CI14X2(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 4):
for y1 in range(y, y + 4):
for x1 in range(x, x + 4):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = (pal[pixel & 0x3FFF] & 0xFF000000) >> 24
g = (pal[pixel & 0x3FFF] & 0x00FF0000) >> 16
b = (pal[pixel & 0x3FFF] & 0x0000FF00) >> 8
a = (pal[pixel & 0x3FFF] & 0x000000FF) >> 0
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
if __name__=='__main__':
app = wx.PySimpleApp()
app.MainLoop()
TPL(*sys.argv[1:]).toScreen()

818
WiiPy/nand.py Normal file
View File

@ -0,0 +1,818 @@
from binascii import *
from struct import *
from common import *
from title import *
from formats import *
class NAND:
"""This class performs all NAND related things. It includes functions to copy a title (given the TMD) into the correct structure as the Wii does, and has an entire ES-like system. Parameter f to the initializer is the folder that will be used as the NAND root."""
def __init__(self, f):
self.f = f
if(not os.path.isdir(f)):
os.mkdir(f)
self.perms = f + "/permission.txt"
if(not os.path.isfile(self.perms)):
open(self.perms, "wb").close()
self.newDirectory("/sys", "rwrw--", 0)
self.newFile("/sys/uid.sys", "rwrw--", 0)
self.UID = uidsys(self.f + "/sys/uid.sys")
self.newDirectory("/meta", "rwrwrw", 0x0001, 0x0000000100000002)
self.newDirectory("/import", "rwrw--", 0x0000)
self.newDirectory("/shared1", "rwrw--", 0x0000)
self.newDirectory("/shared2", "rwrwrw", 0x0000)
self.newFile("/sys/cc.sys", "rwrw--", 0x0000)
self.newFile("/sys/cert.sys", "rwrwr-", 0x0000)
self.newFile("/sys/space.sys", "rwrw--", 0x0000)
self.newDirectory("/ticket", "rwrw--", 0x0000)
self.newDirectory("/title", "rwrwr-", 0x0000)
self.newDirectory("/tmp", "rwrwrw", 0x0000)
self.ES = ESClass(self)
self.ISFS = ISFSClass(self)
self.ES._setisfs()
self.ISFS._setes()
self.contentmap = ContentMap(self.f + "/shared1/content.map")
def hasPermissionEntry(self, dir):
pfp = open(self.perms, "rb")
data = pfp.read()
pfp.close()
ret = data.find(dir)
if(ret == -1):
return 0
return 1
def removePermissionEntry(self, dir):
pfp = open(self.perms, "rb")
data = pfp.read()
pfp.close()
ret = data.find(dir)
if(ret == -1):
return 0
newlineloc = -1
for i in range(ret):
if(data.startswith("\n", i)):
newlineloc = i + 1
endloc = data.find("\n", newlineloc)
pfp = open(self.perms, "rb")
data = pfp.read(newlineloc)
pfp.seek(endloc + 1)
data += pfp.read()
pfp.close()
pfp = open(self.perms, "wb")
pfp.write(data)
pfp.close()
return 1
def _getFilePermissionBase(self, dir, loc):
pfp = open(self.perms, "rb")
data = pfp.read()
pfp.close()
ret = data.find(dir)
if(ret == -1):
return 0
newlineloc = 0
for i in range(ret):
if(data.startswith("\n", i)):
newlineloc = i + 1
endloc = data.find("\n", newlineloc)
pfp = open(self.perms, "rb")
if(loc > 0):
loc *= 2
pfp.seek(newlineloc + 1 + loc)
pdata = pfp.read(2)
pfp.close()
return pdata
def getFilePermissionOwner(self, dir):
pdata = self._getFilePermissionBase(dir, 0)
pval = 0
if(pdata[0] == "r"):
pval += 1
if(pdata[1] == "w"):
pval += 2
return pval
def getFilePermissionGroup(self, dir):
pdata = self._getFilePermissionBase(dir, 1)
pval = 0
if(pdata[0] == "r"):
pval += 1
if(pdata[1] == "w"):
pval += 2
return pval
def getFilePermissionOthers(self, dir):
pdata = self._getFilePermissionBase(dir, 2)
pval = 0
if(pdata[0] == "r"):
pval += 1
if(pdata[1] == "w"):
pval += 2
return pval
def getFilePermissionPerms(self, dir):
pfp = open(self.perms, "rb")
data = pfp.read()
pfp.close()
ret = data.find(dir)
if(ret == -1):
return 0
newlineloc = 0
for i in range(ret):
if(data.startswith("\n", i)):
newlineloc = i + 1
endloc = data.find("\n", newlineloc)
pfp = open(self.perms, "rb")
pfp.seek(newlineloc + 1)
pdata = pfp.read(6)
pfp.close()
return pdata
def _setFilePermissionBase(self, dir, loc, val):
pfp = open(self.perms, "rb")
data = pfp.read()
pfp.close()
ret = data.find(dir)
if(ret == -1):
return 0
newlineloc = 0
for i in range(ret):
if(data.startswith("\n", i)):
newlineloc = i + 1
endloc = data.find("\n", newlineloc)
pfp = open(self.perms, "rb")
if(loc > 0):
loc *= 2
pfp.seek(newlineloc + 1 + loc)
pfp.write(val)
pfp.close()
def setFilePermissionOwner(self, dir, val):
out = ""
if(val & 1):
out += "r"
if(val & 2):
out += "w"
self._setFilePermissionBase(dir, 0, out)
def setFilePermissionGroup(self, dir):
out = ""
if(val & 1):
out += "r"
if(val & 2):
out += "w"
self._setFilePermissionBase(dir, 1, out)
def setFilePermissionOthers(self, dir):
out = ""
if(val & 1):
out += "r"
if(val & 2):
out += "w"
self._setFilePermissionBase(dir, 2, out)
def isFileDirectory(self, dir):
pdata = self._getFilePermissionBase(dir, -1)
pval = 0
if(pdata[0] == "d"):
pval += 1
return pval
def getFilePermissionUID(self, dir):
pfp = open(self.perms, "rb")
data = pfp.read()
pfp.close()
ret = data.find(dir)
if(ret == -1):
return 0
newlineloc = -1
for i in range(ret):
if(data.startswith("\n", i)):
newlineloc = i + 1
endloc = data.find("\n", newlineloc)
pfp = open(self.perms, "rb")
pfp.seek(newlineloc + 8)
uidata = pfp.read(4)
pfp.close()
return int(uidata, 16)
def getFilePermissionGID(self, dir):
pfp = open(self.perms, "rb")
data = pfp.read()
pfp.close()
ret = data.find(dir)
if(ret == -1):
return 0
newlineloc = -1
for i in range(ret):
if(data.startswith("\n", i)):
newlineloc = i + 1
endloc = data.find("\n", newlineloc)
pfp = open(self.perms, "rb")
pfp.seek(newlineloc + 13)
gidata = pfp.read(4)
pfp.close()
return int(gidata, 16)
def setFilePermissionUID(self, dir, val):
pfp = open(self.perms, "rb")
data = pfp.read()
pfp.close()
ret = data.find(dir)
if(ret == -1):
return 0
newlineloc = -1
for i in range(ret):
if(data.startswith("\n", i)):
newlineloc = i + 1
endloc = data.find("\n", newlineloc)
pfp = open(self.perms, "rb")
pfp.seek(newlineloc + 8)
uidata = pfp.write("%04X" % val)
pfp.close()
return int(uidata, 16)
def setFilePermissionGID(self, dir, val):
pfp = open(self.perms, "rb")
data = pfp.read()
pfp.close()
ret = data.find(dir)
if(ret == -1):
return 0
newlineloc = -1
for i in range(ret):
if(data.startswith("\n", i)):
newlineloc = i + 1
endloc = data.find("\n", newlineloc)
pfp = open(self.perms, "rb")
pfp.seek(newlineloc + 13)
gidata = pfp.write("%04X" % val)
pfp.close()
return int(gidata, 16)
def addPermissionEntry(self, uid, permissions, dir, groupid):
pfp = open(self.perms, "rb")
data = pfp.read()
pfp.close()
data += "%s " % permissions
if(uid == None):
print "UID is None!\n"
try:
data += hexdump(uid, "")
data += " "
except:
try:
data += "%04X " % uid
except:
print "UID type couldn't be confirmed..."
return
try:
data += hexdump(groupid, "")
data += " "
except:
try:
data += "%04X " % groupid
except:
print "GID type couldn't be confirmed..."
return
data += "%s\n" % dir
pfp = open(self.perms, "wb")
pfp.write(data)
pfp.close()
def newDirectory(self, dir, perms, groupid, permtitle = 0):
"""Creates a new directory in the NAND filesystem and adds a permissions entry."""
if(not self.hasPermissionEntry(dir)):
if(permtitle == 0):
if(not os.path.isdir(self.f + dir)):
os.mkdir(self.f + dir)
self.addPermissionEntry(0, "d" + perms, dir, groupid)
else:
if(not os.path.isdir(self.f + dir)):
os.mkdir(self.f + dir)
self.addPermissionEntry(self.getUIDForTitleFromUIDSYS(permtitle), "d" + perms, dir, groupid)
def newFile(self, fil, perms, groupid, permtitle = 0):
"""Creates a new file in the NAND filesystem and adds a permissions entry."""
if(not self.hasPermissionEntry(fil)):
if(permtitle == 0):
if(not os.path.isfile(self.f + fil)):
open(self.f + fil, "wb").close()
self.addPermissionEntry(0, "-" + perms, fil, groupid)
else:
if(not os.path.isfile(self.f + fil)):
open(self.f + fil, "wb").close()
self.addPermissionEntry(self.getUIDForTitleFromUIDSYS(permtitle), "-" + perms, fil, groupid)
def removeFile(self, fil):
"""Deletes a file, and removes the permissions entry."""
os.remove(self.f + fil)
self.removePermissionEntry(fil)
def getContentByHashFromContentMap(self, hash):
"""Gets the filename of a shared content with SHA1 hash ``hash''. This includes the NAND prefix."""
return self.f + self.contentmap.contentByHash(hash)
def addContentToContentMap(self, contentid, hash):
"""Adds a content with content ID ``contentid'' and SHA1 hash ``hash'' to the content.map."""
return self.contentmap.addContentToMap(contentid, hash)
def addHashToContentMap(self, hash):
"""Adds a content with SHA1 hash ``hash'' to the content.map. It returns the content ID used."""
return self.contentmap.addHashToMap(hash)
def getContentCountFromContentMap(self):
"""Returns the number of contents in the content.map."""
return self.contentmap.contentCount()
def getContentHashesFromContentMap(self, count):
"""Returns the hashes of ``count'' contents in the content.map."""
return self.contentmap.contentHashes(count)
def addTitleToUIDSYS(self, title):
"""Adds the title with title ID ``title'' to the uid.sys file."""
return self.UID.addTitle(title)
def getTitleFromUIDSYS(self, uid):
"""Gets the title ID with UID ``uid'' from the uid.sys file."""
return self.UID.getTitle(uid)
def getUIDForTitleFromUIDSYS(self, title):
"""Gets the UID for title ID ``title'' from the uid.sys file."""
ret = self.UID.getUIDForTitle(title)
return ret
def addTitleToMenu(self, tid):
"""Adds a title to the System Menu."""
a = iplsave(self.f + "/title/00000001/00000002/data/iplsave.bin", self)
type = 0
if(((tid & 0xFFFFFFFFFFFFFF00) == 0x0001000248414300) or ((tid & 0xFFFFFFFFFFFFFF00) == 0x0001000248414200)):
type = 1
a.addTitle(0,0, 0, tid, 1, type)
def addDiscChannelToMenu(self, x, y, page, movable):
"""Adds the disc channel to the System Menu."""
a = iplsave(self.f + "/title/00000001/00000002/data/iplsave.bin", self)
a.addDisc(x, y, page, movable)
def deleteTitleFromMenu(self, tid):
"""Deletes a title from the System Menu."""
a = iplsave(self.f + "/title/00000001/00000002/data/iplsave.bin", self)
a.deleteTitle(tid)
def importTitle(self, prefix, tmd, tik, add_to_menu = True, is_decrypted = False, result_decrypted = False):
"""When passed a prefix (the directory to obtain the .app files from, sorted by content id), a TMD instance, and a Ticket instance, this will add that title to the NAND base folder specified in the constructor. If add_to_menu is True, the title (if neccessary) will be added to the menu. The default is True. Unless is_decrypted is set, the contents are assumed to be encrypted. If result_decrypted is True, then the contents will not end up decrypted."""
self.ES.AddTitleStart(tmd, None, None, is_decrypted, result_decrypted, use_version = True)
self.ES.AddTitleTMD(tmd)
self.ES.AddTicket(tik)
contents = tmd.getContents()
for i in range(tmd.tmd.numcontents):
self.ES.AddContentStart(tmd.tmd.titleid, contents[i].cid)
fp = open(prefix + "/%08x.app" % contents[i].cid, "rb")
data = fp.read()
fp.close()
self.ES.AddContentData(contents[i].cid, data)
self.ES.AddContentFinish(contents[i].cid)
self.ES.AddTitleFinish()
if(add_to_menu == True):
if(((tmd.tmd.titleid >> 32) != 0x00010008) and ((tmd.tmd.titleid >> 32) != 0x00000001)):
self.addTitleToMenu(tmd.tmd.titleid)
def createWADFromTitle(self, title, cert, output, version=0):
tmdpth = self.f + "/title/%08x/%08x/content/title.tmd" % (title >> 32, title & 0xFFFFFFFF)
if(version != 0):
tmdpth += ".%d" % version
tmd = TMD.loadFile(tmdpth)
if(not os.path.isdir("export")):
os.mkdir("export")
tmd.fakesign()
tmd.dumpFile("export/tmd")
tik = Ticket.loadFile(self.f + "/ticket/%08x/%08x.tik" % (title >> 32, title & 0xFFFFFFFF))
tik.fakesign()
tik.dumpFile("export/tik")
contents = tmd.getContents()
for i in range(tmd.tmd.numcontents):
path = ""
if(contents[i].type == 0x0001):
path = self.f + "/title/%08x/%08x/content/%08x.app" % (title >> 32, title & 0xFFFFFFFF, contents[i].cid)
elif(contents[i].type == 0x8001):
path = self.getContentByHashFromContentMap(contents[i].hash)
fp = open(path, "rb")
data = fp.read()
fp.close()
fp = open("export/%08x.app" % contents[i].index, "wb")
fp.write(data)
fp.close()
fp = open(cert, "rb")
data = fp.read()
fp.close()
fp = open("export/cert", "wb")
fp.write(data)
fp.close()
WAD("export").pack(output)
for i in range(tmd.tmd.numcontents):
os.remove("export/%08x.app" % contents[i].index)
os.remove("export/tmd")
os.remove("export/tik")
os.remove("export/cert")
os.rmdir("export")
class ISFSClass:
"""This class contains an interface to the NAND that simulates the permissions system and all other aspects of the ISFS.
The nand argument to the initializer is a NAND object."""
class ISFSFP:
def __init__(self, file, mode):
self.fp = open(file, mode)
self.loc = 0
self.size = len(self.fp.read())
self.fp.seek(0)
self.SEEK_SET = 0
self.SEEK_CUR = 1
self.SEEK_END = 2
def seek(self, where, whence = 0):
if(whence == self.SEEK_SET):
self.loc = where
if(whence == self.SEEK_CUR):
self.loc += where
if(whence == self.SEEK_END):
self.loc = self.size - where
self.fp.seek(self.loc)
return self.loc
def close(self):
self.fp.close()
self.loc = 0
self.size = 0
def write(self, data):
leng = self.fp.write(data)
self.loc += leng
return leng
def read(self, length=""):
if(length == ""):
self.loc = self.size
return self.fp.read()
self.loc += length
return self.fp.read(length)
def __init__(self, nand):
self.nand = nand
self.f = nand.f
self.ES = None
def _setes(self):
self.ES = self.nand.ES
def _checkPerms(self, mode, uid, gid, own, grp, oth):
if(uid == self.ES.title):
if(own & mode):
return 1
elif(gid == self.ES.group):
if(grp & mode):
return 1
elif(oth & mode):
return 1
else:
return 0
def Open(self, file, mode):
if(not os.path.isfile(self.f + file)):
return None
modev = 0
if(mode.find("r") != -1):
modev = 1
elif(mode.find("w") != -1):
modev = 2
if(mode.find("+") != -1):
modev = 3
uid = self.nand.getFilePermissionUID(file)
gid = self.nand.getFilePermissionGID(file)
own = self.nand.getFilePermissionOwner(file)
grp = self.nand.getFilePermissionGroup(file)
oth = self.nand.getFilePermissionOthers(file)
if(self._checkPerms(modev, uid, gid, own, grp, oth) == 0):
return -41
return self.ISFSFP(self.f + file, mode)
def Close(self, fp):
fp.close()
def Delete(self, file):
uid = self.nand.getFilePermissionUID(file)
gid = self.nand.getFilePermissionGID(file)
own = self.nand.getFilePermissionOwner(file)
grp = self.nand.getFilePermissionGroup(file)
oth = self.nand.getFilePermissionOthers(file)
if(self._checkPerms(2, uid, gid, own, grp, oth) == 0):
return -41
self.nand.removeFile(file)
return 0
def CreateFile(self, filename, perms):
dirabove = filename
uid = self.nand.getFilePermissionUID(dirabove)
gid = self.nand.getFilePermissionGID(dirabove)
own = self.nand.getFilePermissionOwner(dirabove)
grp = self.nand.getFilePermissionGroup(dirabove)
oth = self.nand.getFilePermissionOthers(dirabove)
if(self._checkPerms(2, uid, gid, own, grp, oth) == 0):
return -41
self.nand.newFile(filename, perms, self.ES.group, self.ES.title)
return 0
def Write(self, fp, data):
return fp.write(data)
def Read(self, fp, length=""):
return fp.read(length)
def Seek(self, fp, where, whence):
return fp.seek(where, whence)
def CreateDir(self, dirname, perms):
dirabove = dirname
uid = self.nand.getFilePermissionUID(dirabove)
gid = self.nand.getFilePermissionGID(dirabove)
own = self.nand.getFilePermissionOwner(dirabove)
grp = self.nand.getFilePermissionGroup(dirabove)
oth = self.nand.getFilePermissionOthers(dirabove)
if(self._checkPerms(2, uid, gid, own, grp, oth) == 0):
return -41
self.nand.newDirectory(dirname, perms, self.ES.group, self.ES.title)
return 0
def GetAttr(self, filename): # Wheeee, stupid haxx to put all the numbers into one return value!
ret = self.nand.getFilePermissionUID(filename)
ret += (self.nand.getFilePermissionGID(filename) << 16)
ret += (self.nand.getFilePermissionOwner(filename) << 32)
ret += (self.nand.getFilePermissionGroup(filename) << 34)
ret += (self.nand.getFilePermissionOthers(filename) << 36)
return ret
def splitAttrUID(self, attr):
return attr & 0xFFFF
def splitAttrGID(self, attr):
return (attr >> 16) & 0xFFFF
def splitAttrOwner(self, attr):
return (attr >> 32) & 0xFF
def splitAttrGroup(self, attr):
return (attr >> 34) & 0xFF
def splitAttrOthers(self, attr):
return (attr >> 36) & 0xFF
def Rename(self, fileold, filenew):
uid = self.nand.getFilePermissionUID(fileold)
gid = self.nand.getFilePermissionGID(fileold)
own = self.nand.getFilePermissionOwner(fileold)
grp = self.nand.getFilePermissionGroup(fileold)
oth = self.nand.getFilePermissionOthers(fileold)
if(self._checkPerms(2, uid, gid, own, grp, oth) == 0):
return -41
fld = self.nand.isFileDirectory(fileold)
if(fld):
print "Directory moving is busted ATM. Will fix laterz.\n"
return -40
fp = self.Open(fileold, "rb")
data = fp.Read()
fp.close()
perms = ""
if(own & 1):
perms += "r"
else:
perms += "-"
if(own & 2):
perms += "w"
else:
perms += "-"
if(grp & 1):
perms += "r"
else:
perms += "-"
if(grp & 2):
perms += "w"
else:
perms += "-"
if(oth & 1):
perms += "r"
else:
perms += "-"
if(oth & 2):
perms += "w"
else:
perms += "-"
self.CreateFile(filenew, perms)
fp = self.Open(filenew, "wb")
fp.write(data)
fp.close()
self.Delete(fileold)
return 0
def SetAttr(self, filename, uid, gid=0, owner=0, group=0, others=0):
uidx = self.nand.getFilePermissionUID(filename)
gidx = self.nand.getFilePermissionGID(filename)
own = self.nand.getFilePermissionOwner(filename)
grp = self.nand.getFilePermissionGroup(filename)
oth = self.nand.getFilePermissionOthers(filename)
if(self._checkPerms(2, uidx, gidx, own, grp, oth) == 0):
return -41
self.nand.setFilePermissionUID(filename, uid)
self.nand.setFilePermissionGID(filename, gid)
self.nand.setFilePermissionOwner(filename, owner)
self.nand.setFilePermissionGroup(filename, group)
self.nand.setFilePermissionOthers(filename, others)
return 0
class ESClass:
"""This class performs all services relating to titles installed on the Wii. It is a clone of the libogc ES interface.
The nand argument to the initializer is a NAND object."""
def __init__(self, nand):
self.title = 0x0000000100000002
self.group = 0x0001
self.ticketadded = 0
self.tmdadded = 0
self.workingcid = 0
self.workingcidcnt = 0
self.nand = nand
self.f = nand.f
self.ISFS = None
def _setisfs(self):
self.ISFS = self.nand.ISFS
def getContentIndexFromCID(self, tmd, cid):
"""Gets the content index from the content id cid referenced to in the TMD instance tmd."""
for i in range(tmd.tmd.numcontents):
if(cid == tmd.contents[i].cid):
return tmd.contents[i].index
return None
def Identify(self, id, version=0):
if(not os.path.isfile(self.f + "/ticket/%08x/%08x.tik" % (id >> 32, id & 0xFFFFFFFF))):
return None
tik = Ticket.loadFile(self.f + "/ticket/%08x/%08x.tik" % (id >> 32, id & 0xFFFFFFFF))
titleid = tik.titleid
path = "/title/%08x/%08x/content/title.tmd" % (titleid >> 32, titleid & 0xFFFFFFFF)
if(version):
path += ".%d" % version
if(not os.path.isfile(self.f + path)):
return None
tmd = TMD.loadFile(self.f + path)
self.title = titleid
self.group = tmd.tmd.group_id
return self.title
def GetTitleID(self):
return self.title
def GetDataDir(self, titleid):
"""When passed a titleid, it will get the Titles data directory. If there is no title associated with titleid, it will return None."""
if(not os.path.isdir(self.f + "/title/%08x/%08x/data" % (titleid >> 32, titleid & 0xFFFFFFFF))):
return None
return self.f + "/title/%08x/%08x/data" % (titleid >> 32, titleid & 0xFFFFFFFF)
def GetStoredTMD(self, titleid, version=0):
"""Gets the TMD for the specified titleid and version"""
path = "/title/%08x/%08x/content/title.tmd" % (titleid >> 32, titleid & 0xFFFFFFFF)
if(version):
path += ".%d" % version
if(not os.path.isfile(self.f + path)):
return None
return TMD.loadFile(self.f + path)
def GetTitleContentsCount(self, titleid, version=0):
"""Gets the number of contents the title with the specified titleid and version has."""
tmd = self.GetStoredTMD(titleid, version)
if(tmd == None):
return 0
return tmd.tmd.numcontents
def GetTitleContents(self, titleid, count, version=0):
"""Returns a list of content IDs for title id ``titleid'' and version ``version''. It will return, at maximum, ``count'' entries."""
tmd = self.GetStoredTMD(titleid, version)
if(tmd == None):
return 0
contents = tmd.getContents()
out = ""
for z in range(count):
out += a2b_hex("%08X" % contents[z].cid)
return out
def GetNumSharedContents(self):
"""Gets how many shared contents exist on the NAND"""
return self.nand.getContentCountFromContentMap()
def GetSharedContents(self, cnt):
"""Gets cnt amount of shared content hashes"""
return self.nand.getContentHashesFromContentMap(cnt)
def AddTitleStart(self, tmd, certs, crl, is_decrypted = False, result_decrypted = True, use_version = False):
self.nand.addTitleToUIDSYS(tmd.tmd.titleid)
self.nand.newDirectory("/title/%08x" % (tmd.tmd.titleid >> 32), "rwrwr-", 0x0000)
self.nand.newDirectory("/title/%08x/%08x" % (tmd.tmd.titleid >> 32, tmd.tmd.titleid & 0xFFFFFFFF), "rwrwr-", 0x0000)
self.nand.newDirectory("/title/%08x/%08x/content" % (tmd.tmd.titleid >> 32, tmd.tmd.titleid & 0xFFFFFFFF), "rwrw--", 0x0000)
self.nand.newDirectory("/title/%08x/%08x/data" % (tmd.tmd.titleid >> 32, tmd.tmd.titleid & 0xFFFFFFFF), "rw----", tmd.tmd.group_id, tmd.tmd.titleid)
self.nand.newDirectory("/ticket/%08x" % (tmd.tmd.titleid >> 32), "rwrw--", 0x0000)
self.workingcids = array.array('L')
self.wtitleid = tmd.tmd.titleid
self.is_decrypted = is_decrypted
self.result_decrypted = result_decrypted
self.use_version = use_version
return
def AddTicket(self, tik):
"""Adds ticket to the title being added."""
tik.dumpFile(self.f + "/tmp/title.tik")
self.ticketadded = 1
def DeleteTicket(self, tikview):
"""Deletes the ticket relating to tikview
(UNIMPLEMENTED!)"""
return
def AddTitleTMD(self, tmd):
"""Adds TMD to the title being added."""
tmd.dumpFile(self.f + "/tmp/title.tmd")
self.tmdadded = 1
def AddContentStart(self, titleid, cid):
"""Starts adding a content with content id cid to the title being added with ID titleid."""
if((self.workingcid != 0) and (self.workingcid != None)):
"Trying to start an already existing process"
return -41
if(self.tmdadded):
a = TMD.loadFile(self.f + "/tmp/title.tmd")
else:
a = TMD.loadFile(self.f + "/title/%08x/%08x/content/title.tmd.%d" % (self.wtitleid >> 32, self.wtitleid & 0xFFFFFFFF, tmd.tmd.title_version))
x = self.getContentIndexFromCID(a, cid)
if(x == None):
"Not a valid Content ID"
return -43
self.workingcid = cid
self.workingfp = open(self.f + "/tmp/%08x.app" % cid, "wb")
return 0
def AddContentData(self, cid, data):
"""Adds data to the content cid being added."""
if(cid != self.workingcid):
"Working on the not current CID"
return -40
self.workingfp.write(data);
return 0
def AddContentFinish(self, cid):
"""Finishes the content cid being added."""
if(cid != self.workingcid):
"Working on the not current CID"
return -40
self.workingfp.close()
self.workingcids.append(cid)
self.workingcidcnt += 1
self.workingcid = None
return 0
def AddTitleCancel(self):
"""Cancels adding a title (deletes the tmp files and resets status)."""
if(self.ticketadded):
self.nand.removeFile("/tmp/title.tik")
self.ticketadded = 0
if(self.tmdadded):
self.nand.removeFile("/tmp/title.tmd")
self.tmdadded = 0
for i in range(self.workingcidcnt):
self.nand.removeFile("/tmp/%08x.app" % self.workingcids[i])
self.workingcidcnt = 0
self.workingcid = None
def AddTitleFinish(self):
"""Finishes the adding of a title."""
if(self.ticketadded):
tik = Ticket.loadFile(self.f + "/tmp/title.tik")
else:
tik = Ticket.loadFile(self.f + "/ticket/%08x/%08x.tik" % (self.wtitleid >> 32, self.wtitleid & 0xFFFFFFFF))
if(self.tmdadded):
tmd = TMD.loadFile(self.f + "/tmp/title.tmd")
contents = tmd.getContents()
for i in range(self.workingcidcnt):
idx = self.getContentIndexFromCID(tmd, self.workingcids[i])
if(idx == None):
print "Content ID doesn't exist!"
return -42
fp = open(self.f + "/tmp/%08x.app" % self.workingcids[i], "rb")
if(contents[idx].type == 0x0001):
filestr = "/title/%08x/%08x/content/%08x.app" % (self.wtitleid >> 32, self.wtitleid & 0xFFFFFFFF, self.workingcids[i])
elif(contents[idx].type == 0x8001):
num = self.nand.addHashToContentMap(contents[idx].hash)
filestr = "/shared1/%08x.app" % num
self.nand.newFile(filestr, "rwrw--", 0x0000)
outfp = open(self.f + filestr, "wb")
data = fp.read()
titlekey = tik.getTitleKey()
if(self.is_decrypted):
tmpdata = data
else:
tmpdata = Crypto().decryptContent(titlekey, contents[idx].index, data)
if(Crypto().validateSHAHash(tmpdata, contents[idx].hash) == 0):
"Decryption failed! SHA1 mismatch."
return -44
if(self.result_decrypted != True):
if(self.is_decrypted):
tmpdata = Crypto().encryptContent(titlekey, contents[idx].index, data)
else:
tmpdata = data
fp.close()
outfp.write(tmpdata)
outfp.close()
if(self.tmdadded and self.use_version):
self.nand.newFile("/title/%08x/%08x/content/title.tmd.%d" % (self.wtitleid >> 32, self.wtitleid & 0xFFFFFFFF, tmd.tmd.title_version), "rwrw--", 0x0000)
tmd.dumpFile(self.f + "/title/%08x/%08x/content/title.tmd.%d" % (self.wtitleid >> 32, self.wtitleid & 0xFFFFFFFF, tmd.tmd.title_version))
elif(self.tmdadded):
self.nand.newFile("/title/%08x/%08x/content/title.tmd" % (self.wtitleid >> 32, self.wtitleid & 0xFFFFFFFF), "rwrw--", 0x0000)
tmd.dumpFile(self.f + "/title/%08x/%08x/content/title.tmd" % (self.wtitleid >> 32, self.wtitleid & 0xFFFFFFFF))
if(self.ticketadded):
self.nand.newFile("/ticket/%08x/%08x.tik" % (self.wtitleid >> 32, self.wtitleid & 0xFFFFFFFF), "rwrw--", 0x0000)
tik.dumpFile(self.f + "/ticket/%08x/%08x.tik" % (self.wtitleid >> 32, self.wtitleid & 0xFFFFFFFF))
self.AddTitleCancel()
return 0

0
WiiPy/tests/__init__.py Normal file
View File

95
WiiPy/tests/bannerbin.py Normal file
View File

@ -0,0 +1,95 @@
import Wii, os, sys, shutil
def packbanner()
bannerbin = U8()
bannerbin['arc'] = None #dir
bannerbin['arc/blyt'] = None
bannerbin['arc/anim'] = None
bannerbin['arc/timg'] = None
# then do
origdir = os.getcwd()
for files in os.walk(origdir + 'arc/timg/')
bannerbin['arc/timg/' + file] = open(file, "rb").read()
for files in os.walk(origdir + 'arc/anim/')
bannerbin['arc/anim/' + file] = open(file, "rb").read()
for files in os.walk(origdir + 'arc/blyt/')
bannerbin['arc/blyt/' + file] = open(file, "rb").read()
fn = open("banner.bin", "w+b")
fn.write(u8object.dumpFile())
fn.close()
def doPack():
exchange = [sys.argv[2], sys.argv[3], sys.argv[4]]
global banneru8, iconu8
print "Unpacking WAD..."
wad = wii.WAD.loadFile("squid.wad")
title = wii.IMET(wad[0]).getTitle()
print "Unpacking 00000000.app..."
wad[0] = wii.IMET(wad[0]).remove()
meta = wii.U8.load(wad[0])
prog = 20
for i, item in enumerate(exchange):
if(item == ""): #skip what doesn't get changed
continue
if(i == 0):
bin = "banner"
print "Replacing banner.bin..."
elif(i == 1):
bin = "icon"
print "Replacing icon.bin..."
else:
bin = "sound"
print "Replacing sound.bin..."
if(item[len(item) - 3:] == "app" or item[len(item) - 3:] == "bnr" or item[len(item - 3):] == "wad"):
if(item[len(item) - 3:] == "wad"):
wad2 = wii.WAD.loadFile(item)
wad2[0] = wii.IMET(wad2[0]).remove()
meta2 = wii.U8.load(wad2[0])
else:
meta2 = wii.IMET.loadFile(item).remove()
bin2 = meta2['meta/%s.bin' % bin]
elif(item[len(item) - 3:] == "bin"):
bin2 = wii.U8.loadFile(item)
else:
continue #only bin, wad, bnr and app are supported
meta['arc/%s.bin' % bin] = bin2.dump()
print "Unpacking banner.bin..."
meta['meta/banner.bin'] = wii.IMD5(meta['meta/banner.bin']).remove()
meta['meta/banner.bin'] = wii.LZ77(meta['meta/banner.bin']).remove()
banneru8 = wii.U8.load(meta['meta/banner.bin'])
print "Unpacking icon.bin..."
meta['meta/icon.bin'] = wii.IMD5(meta['meta/icon.bin']).remove()
meta['meta/icon.bin'] = wii.LZ77(meta['meta/icon.bin']).remove()
iconu8 = wii.U8.load(meta['meta/icon.bin'])
print "Packing banner.bin..."
meta['meta/banner.bin'] = banneru8.dump()
meta['meta/banner.bin'] = wii.IMD5(meta['meta/banner.bin']).add()
print "Packing icon.bin..."
meta['meta/icon.bin'] = iconu8.dump()
meta['meta/icon.bin'] = wii.IMD5(meta['meta/icon.bin']).add()
print "Packing 00000000.app..."
#meta['meta/sound.bin'] = open('wadunpack/00000000_app_out/meta/sound.bin', 'rb').read()
langs = []
wad[0] = meta.dump()
wad[0] = wii.IMET(wad[0]).add(len(meta['meta/icon.bin']), len(meta['meta/banner.bin']), len(meta['meta/sound.bin']), title, langs)
print "Packing WAD..."
wad.dumpFile("squid.wad")
packbanner()
doPack()

30
WiiPy/tests/fakesign.py Normal file
View File

@ -0,0 +1,30 @@
from disc import *
from title import *
from Struct import Struct
import os
def fakesignPartition(self, iso, index)
iso = WOD(iso)
iso.openPartition(index)
fstBuf = iso.getFst() "
fn = open(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + 'appldr.bin', 'w+b')
fn.write(iso.getPartitionApploader()) #saved to cwd/GAMEID/PARTITION/file
fn.close()
fn = open(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + 'h3.bin', 'w+b')
fn.write(iso.getPartitionH3Table())
fn.close()
fn = open(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + 'main.dol', 'w+b')
fn.write(iso.getPartitionMainDol())
fn.close()
fn = open(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + 'fst.bin', 'w+b')
fn.write(fstBuf)
fn.close()
fileNumber = struct.unpack(">I", fstBuf[0x8:0xc])[0]
fileObject = iso.fstObject("", iso)
iso.parseFst(fstBuf, fstBuf[12 * fileNumber:], 0, fileObject)
fileObject.write(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/")
fileObject.close()
isoTik = Ticket(iso.getPartitionTik())
isoTik.dump(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + "tik")
isoTMD = TMD(iso.getPartitionTmd())
isoTMD.dump(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + "tmd")

5
WiiPy/tests/imd5sign.py Normal file
View File

@ -0,0 +1,5 @@
import Wii
import sys
for elem in sys.argv:
Wii.IMD5(elem).add(elem)

26
WiiPy/tests/sysmenu.py Normal file
View File

@ -0,0 +1,26 @@
import os, Wii
print 'Enter the sysmenu version you want then just wait...'
version = int(input()) #97
#Wii.NUS(0x0000000100000002, version).download('0000000100000002ver' + str(version))
os.chdir('0000000100000002ver' + str(version))
print 'Tmd dump :\n'
print '%s' % Wii.TMD().loadFile('tmd')
print 'Now unpacking all the archives in there :3\n'
for root, dirs, files in os.walk(os.getcwd()):
for name in files:
print '%s' % name
location = os.getcwd() + '/' + str(name)
if name == '00000000.app':
print 'IMET Title : %s' % Wii.IMET(name).getTitle()
if open(location).read(4) == '\x55\xaa\x38\x2d':
print 'Now unpacking the u8 archive %s' % location
try:
Wii.U8().loadFile(location)
except:
print "fix the U8 code!"
if open(location).read(4) == '\x43\x43\x46\x00':
print 'Now unpacking the CCF archive %s' % location
Wii.CCF(location).decompress()

View File

@ -0,0 +1,10 @@
import os
from U8 import *
from title import WAD
sysmenuWad = WAD('/home/giuseppe/Scrivania/RVL-WiiSystemmenu-v258.wad')
sysmenuWad.unpack('/home/giuseppe/Scrivania/sysdump')
for file in os.listdir('/home/giuseppe/Scrivania/sysdump'):
if open('/home/giuseppe/Scrivania/sysdump/' + file).read(4) == '\x55\xaa\x38\x2d':
U8('/home/giuseppe/Scrivania/sysdump/' + file).unpack('/home/giuseppe/Scrivania/sysdump/' + file + '_decompressed/')

25
WiiPy/tests/testDISC.py Normal file
View File

@ -0,0 +1,25 @@
from disc import *
from title import *
from Struct import Struct
import os
iso = WOD('/enter/other/wii/SUPER_MARIO_GALAXY.iso')
iso.openPartition(1)
#print '%s' % iso
#iso.decryptAll()
#open('appldr.bin', 'w+b').write(iso.getPartitionApploader())
fstBuf = iso.getFst()
open('fst.bin', 'w+b').write(fstBuf)
fileNumber = struct.unpack(">I", fstBuf[0x8:0xc])[0]
fileObject = iso.fstObject("", iso)
iso.parseFst(fstBuf, fstBuf[12 * fileNumber:], 0, fileObject)
print fileObject.getList()
fileObject.write(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region)
#open('h3.bin', 'w+b').write(iso.getPartitionH3Table())
#isoTik = Ticket('tik.bin')
#print '%s' % isoTik
#open('main.dol', 'w+b').write(iso.getPartitionMainDol())
#isoTmd = TMD(iso.getPartitionTmd())
#print isoTmd

9
WiiPy/tests/testLOC.py Normal file
View File

@ -0,0 +1,9 @@
from formats import locDat
sdLoc = locDat('/home/giuseppe/Scrivania/sysmenu/loc.dat')
print '%s' % sdLoc
#concorsiMii = sdLoc.getTitle(0, 0, 0)
sdLoc.delTitle(0, 0, 0)

9
WiiPy/tests/testSAVE.py Normal file
View File

@ -0,0 +1,9 @@
from savedata import *
save = Savegame('/home/giuseppe/Scrivania/data' + str(4) + '.bin')
save.analyzeHeader()
print '%s' % save
save.getBanner()
for i in range(save.getIconsCount()):
save.getIcon(i)
save.extractFiles()

314
WiiPy/title.py Normal file
View File

@ -0,0 +1,314 @@
from common import *
class TicketView:
"""Creates a ticket view from the Ticket object ``tik''."""
class TikviewStruct(Struct):
__endian__ = Struct.BE
def __format__(self):
self.view = Struct.uint32
self.ticketid = Struct.uint64
self.devicetype = Struct.uint32
self.titleid = Struct.uint64
self.accessmask = Struct.uint16
self.reserved = Struct.string(0x3C)
self.cidxmask = Struct.string(0x40)
self.padding = Struct.uint16
self.limits = Struct.string(96)
def __init__(self, tik):
self.tikview = self.TikviewStruct()
self.tikview.view = 0
self.tikview.ticketid = tik.tik.tikid
self.tikview.devicetype = tik.tik.console
self.tikview.titleid = tik.getTitleID()
self.tikview.accessmask = 0xFFFF # This needs to be changed, I'm sure...
self.tikview.reserved = "\0" * 0x3C
self.tikview.cidxmask = "\xFF" * 0x40 # This needs to be changed, I'm sure...
self.tikview.padding = 0x0000
self.tikview.limits = "\0" * 96
def __str__(self):
out = ""
out += " Ticket View:\n"
out += " Title ID: %08X-%08X\n" % (self.tikview.titleid >> 32, self.tikview.titleid & 0xFFFFFFFF)
out += " Device type: %08X\n" % self.tikview.devicetype
out += " Ticket ID: %016X\n" % self.tikview.ticketid
out += " Access Mask: %04X\n" % self.tikview.accessmask
return out
class Ticket(WiiObject):
"""Creates a ticket from the filename defined in f. This may take a longer amount of time than expected, as it also decrypts the title key. Now supports Korean tickets (but their title keys stay Korean on dump)."""
class TicketStruct(Struct):
__endian__ = Struct.BE
def __format__(self):
self.rsaexp = Struct.uint32
self.rsamod = Struct.string(256)
self.padding1 = Struct.string(60)
self.rsaid = Struct.string(64)
self.padding2 = Struct.string(63)
self.enctitlekey = Struct.string(16)
self.unk1 = Struct.uint8
self.tikid = Struct.uint64
self.console = Struct.uint32
self.titleid = Struct.uint64
self.unk2 = Struct.uint16
self.dlc = Struct.uint16
self.unk3 = Struct.uint64
self.commonkey_index = Struct.uint8
self.reserved = Struct.string(80)
self.unk3 = Struct.uint16
self.limits = Struct.string(96)
self.unk4 = Struct.uint8
def __init__(self):
self.tik = self.TicketStruct()
self.tik.rsaexp = 0x10001
self.tik.rsamod = "\x00" * 256
self.tik.padding1 = "\x00" * 60
self.tik.rsaid = "\x00" * 64
self.tik.padding2 = "\x00" * 63
self.tik.enctitlekey = "\x00" * 16
self.tik.titleid = 0x0000000100000000
self.tik.reserved = "\x00" * 80
self.tik.limits = "\x00" * 96
commonkey = "\xEB\xE4\x2A\x22\x5E\x85\x93\xE4\x48\xD9\xC5\x45\x73\x81\xAA\xF7"
koreankey = "\x63\xB8\x2B\xB4\xF4\x61\x4E\x2E\x13\xF2\xFE\xFB\xBA\x4C\x9B\x7E"
if(self.tik.commonkey_index == 1): #korean, kekekekek!
commonkey = koreankey
self.titlekey = Crypto().decryptTitleKey(commonkey, self.tik.titleid, self.tik.enctitlekey)
def _load(self, data):
self.tik.unpack(data[:len(self.tik)])
commonkey = "\xEB\xE4\x2A\x22\x5E\x85\x93\xE4\x48\xD9\xC5\x45\x73\x81\xAA\xF7"
koreankey = "\x63\xB8\x2B\xB4\xF4\x61\x4E\x2E\x13\xF2\xFE\xFB\xBA\x4C\x9B\x7E"
if(self.tik.commonkey_index == 1): #korean, kekekekek!
commonkey = koreankey
self.titlekey = Crypto().decryptTitleKey(commonkey, self.tik.titleid, self.tik.enctitlekey)
return self
def getTitleKey(self):
"""Returns a string containing the title key."""
return self.titlekey
def getTitleID(self):
"""Returns a long integer with the title id."""
return self.tik.titleid
def setTitleID(self, titleid):
"""Sets the title id of the ticket from the long integer passed in titleid."""
self.tik.titleid = titleid
commonkey = "\xEB\xE4\x2A\x22\x5E\x85\x93\xE4\x48\xD9\xC5\x45\x73\x81\xAA\xF7"
koreankey = "\x63\xB8\x2B\xB4\xF4\x61\x4E\x2E\x13\xF2\xFE\xFB\xBA\x4C\x9B\x7E"
if(self.tik.commonkey_index == 1): #korean, kekekekek!
commonkey = koreankey
self.titlekey = Crypto().decryptTitleKey(commonkey, self.tik.titleid, self.tik.enctitlekey) #This changes the decrypted title key!
def __str__(self):
out = ""
out += " Ticket:\n"
out += " Title ID: %08x-%08x\n" % (self.getTitleID() >> 32, self.getTitleID() & 0xFFFFFFFF)
out += " Title key IV: "
out += hexdump(struct.pack(">Q", self.getTitleID()) + "\x00\x00\x00\x00\x00\x00\x00\x00")
out += "\n"
out += " Title key (encrypted): "
out += hexdump(self.tik.enctitlekey)
out += "\n"
out += " Title key (decrypted): "
out += hexdump(self.getTitleKey())
out += "\n"
return out
def fakesign(self):
"""Fakesigns (or Trucha signs) and dumps the ticket to either fn, if not empty, or overwriting the source if empty. Returns the output filename."""
self.rsamod = self.rsamod = "\x00" * 256
for i in range(65536):
self.tik.unk2 = i
if(Crypto().createSHAHashHex(self.tik.pack())[:2] == "00"):
break
if(i == 65535):
raise ValueError("Failed to fakesign. Aborting...")
def _dump(self):
"""Dumps the ticket to either fn, if not empty, or overwriting the source if empty. **Does not fakesign.** Returns the output filename."""
return self.tik.pack()
def __len__(self):
return len(self.tik)
class TMD(WiiObject):
"""This class allows you to edit TMDs. TMD (Title Metadata) files are used in many places to hold information about titles. The parameter f to the initialization is the filename to open and create a TMD from."""
class TMDContent(Struct):
__endian__ = Struct.BE
def __format__(self):
self.cid = Struct.uint32
self.index = Struct.uint16
self.type = Struct.uint16
self.size = Struct.uint64
self.hash = Struct.string(20)
class TMDStruct(Struct):
__endian__ = Struct.BE
def __format__(self):
self.rsaexp = Struct.uint32
self.rsamod = Struct.string(256)
self.padding1 = Struct.string(60)
self.rsaid = Struct.string(64)
self.version = Struct.uint8[4]
self.iosversion = Struct.uint64
self.titleid = Struct.uint64
self.title_type = Struct.uint32
self.group_id = Struct.uint16
self.reserved = Struct.string(62)
self.access_rights = Struct.uint32
self.title_version = Struct.uint16
self.numcontents = Struct.uint16
self.boot_index = Struct.uint16
self.padding2 = Struct.uint16
#contents follow this
def _load(self, data):
self.tmd.unpack(data[:len(self.tmd)])
pos = len(self.tmd)
for i in range(self.tmd.numcontents):
cont = self.TMDContent()
cont.unpack(data[pos:pos + len(cont)])
pos += len(cont)
self.contents.append(cont)
def __init__(self):
self.tmd = self.TMDStruct()
self.tmd.titleid = 0x0000000100000000
self.contents = []
def getContents(self):
"""Returns a list of contents. Each content is an object with the members "size", the size of the content's decrypted data; "cid", the content id; "type", the type of the content (0x8001 for shared, 0x0001 for standard, more possible), and a 20 byte string called "hash"."""
return self.contents
def setContents(self, contents):
"""This sets the contents in the TMD to the contents you provide in the contents parameter. Also updates the TMD to the appropraite amount of contents."""
self.contents = contents
self.tmd.numcontents = len(contents)
def __str__(self):
out = ""
out += " TMD:\n"
out += " Versions: (todo) %u, CA CRL (todo) %u, Signer CRL (todo) %u, System %u-%u\n" % (0, 0, 0, self.getIOSVersion() >> 32, self.getIOSVersion() & 0xFFFFFFFF)
out += " Title ID: %08x-%08x\n" % (self.getTitleID() >> 32, self.getTitleID() & 0xFFFFFFFF)
out += " Title Type: %u\n" % self.tmd.title_type
out += " Group ID: '%02u'\n" % self.tmd.group_id
out += " Access Rights: 0x%08x\n" % self.tmd.access_rights
out += " Title Version: 0x%04x\n" % self.tmd.title_version
out += " Boot Index: %u\n" % self.getBootIndex()
out += " Contents: \n"
out += " ID Index Type Size Hash\n"
contents = self.getContents()
for i in range(len(contents)):
out += " %08X %-4u 0x%04x %#-12x " % (contents[i].cid, contents[i].index, contents[i].type, contents[i].size)
out += hexdump(contents[i].hash)
out += "\n"
return out
def __len__(self):
contents = self.getContents()
sz = len(self.tmd)
for i in range(len(contents)):
sz += len(contents[i])
return sz
def fakesign(self):
"""Dumps the TMD to the filename specified in fn, if not empty. If that is empty, it overwrites the original. This fakesigns the TMD, but does not update the hashes and the sizes, that is left as a job for you. Returns output filename."""
for i in range(65536):
self.tmd.padding2 = i
data = "" #gotta reset it every time
data += self.tmd.pack()
for i in range(self.tmd.numcontents):
data += self.contents[i].pack()
if(Crypto().createSHAHashHex(data)[:2] == "00"):
break
if(i == 65535):
raise ValueError("Failed to fakesign! Aborting...")
def _dump(self):
"""Same as the :dump: function, but does not fakesign the TMD. Also returns output filename."""
data = ""
data += self.tmd.pack()
for i in range(self.tmd.numcontents):
data += self.contents[i].pack()
return data
def getTitleID(self):
"""Returns the long integer title id."""
return self.tmd.titleid
def setTitleID(self, titleid):
"""Sets the title id to the long integer specified in the parameter titleid."""
self.tmd.titleid = titleid
def getIOSVersion(self):
"""Returns the IOS version the title will run off of."""
return self.tmd.iosversion
def setIOSVersion(self, version):
"""Sets the IOS version the title will run off of to the arguement version."""
self.tmd.iosverison = version
def getBootIndex(self):
"""Returns the boot index of the TMD."""
return self.tmd.boot_index
def setBootIndex(self, index):
"""Sets the boot index of the TMD to the value of index."""
self.tmd.boot_index = index
class NUS:
"""This class can download titles from NUS, or Nintendo Update Server. The titleid parameter is the long integer version of the title to download. The version parameter is optional and specifies the version to download. If version is not given, it is assumed to be the latest version on NUS."""
def __init__(self, titleid, version = None):
self.titleid = titleid
self.baseurl = "http://nus.cdn.shop.wii.com/ccs/download/%08x%08x/" % (titleid >> 32, titleid & 0xFFFFFFFF)
self.version = version
def download(self, fn = "", decrypt = True, useidx = True):
"""This will download a title from NUS into a directory either specified by fn (if it is not empty) or a directory created by the title id in hex form. If decrypt is true, it will decrypt the contents, otherwise it will not. A certs file is always created to enable easy WAD Packing. The parameter useidx specifies wheither to use the index or the content id for the file naming (default is index)."""
if(fn == ""):
fn = "%08x%08x" % (self.titleid >> 32, self.titleid & 0xFFFFFFFF)
try:
os.mkdir(fn)
except:
pass
os.chdir(fn)
certs = ""
rawtmd = urllib.urlopen("http://nus.cdn.shop.wii.com/ccs/download/0000000100000002/tmd.289").read()
rawtik = urllib.urlopen("http://nus.cdn.shop.wii.com/ccs/download/0000000100000002/cetk").read()
certs += rawtik[0x2A4:0x2A4 + 0x300] #XS
certs += rawtik[0x2A4 + 0x300:] #CA (tik)
certs += rawtmd[0x328:0x328 + 0x300] #CP
if(Crypto().createMD5HashHex(certs) != "7ff50e2733f7a6be1677b6f6c9b625dd"):
raise ValueError("Failed to create certs! MD5 mistatch.")
open("cert", "wb").write(certs)
if(self.version == None):
versionstring = ""
else:
versionstring = ".%u" % self.version
urllib.urlretrieve(self.baseurl + "tmd" + versionstring, "tmd")
tmd = TMD.loadFile("tmd")
tmd.dumpFile("tmd") # strip certs
urllib.urlretrieve(self.baseurl + "cetk", "tik")
tik = Ticket.loadFile("tik")
tik.dumpFile("tik") # strip certs
if(decrypt):
titlekey = tik.getTitleKey()
contents = tmd.getContents()
for content in contents:
output = content.cid
if(useidx):
output = content.index
urllib.urlretrieve(self.baseurl + ("%08x" % content.cid), "%08x.app" % output)
if(decrypt):
data = open("%08x.app" % output, "rb").read(content.size)
tmpdata = Crypto().decryptContent(titlekey, content.index, data)
if(Crypto().validateSHAHash(tmpdata, content.hash) == 0):
raise ValueError("Decryption failed! SHA1 mismatch.")
open("%08x.app" % output, "wb").write(tmpdata)
os.chdir("..")

51
WiiPy/tools/NUStool.py Normal file
View File

@ -0,0 +1,51 @@
#----------------------------------------------------------------------
# NUS Tool - a simple command line tool for NUS downloading.
# (c) 2009 |Omega and #HACKERCHANNEL Productions.
#
# Wii.py (c) Xuzz, SquidMan, megazig, TheLemonMan, |Omega, and Matt_P.
#----------------------------------------------------------------------
import os, sys, Wii, shutil
if len(sys.argv) < 3:
print "Usage: python %s -(d/p) titleid version [decrypt/fakesign](True/False) [download/pack](dirname/filename)" % sys.argv[0]
sys.exit()
print sys.argv
titleid = int(sys.argv[2], 16)
print titleid
ver = int(sys.argv[3])
print type(ver)
print ver
if not (sys.argv[4]) and sys.argv[1] == "-d" :
decrypt = False
else:
decrypt = True
if len(sys.argv) < 6:
tmp = "tmp"
else:
tmp = sys.argv[5]
#downloading
print "Downloading..."
if(ver != 0):
Wii.NUS(titleid, ver).download(tmp, decrypt = decrypt)
else:
Wii.NUS(titleid).download(tmp, decrypt = decrypt)
print "Done downloading!"
#wadpacking
if sys.argv[1] == "-p":
print "packing"
if len(sys.argv[5]) != 0:
wadfile = str(sys.argv[5]) + ".wad"
else:
wadfile = str(titleid) + "ver" + str(ver) + ".wad"
Wii.WAD.loadDir(tmp).dumpFile(wadfile, fakesign = sys.argv[4])
if(os.path.isdir(tmp)): #cleanup
shutil.rmtree(tmp)
print"Done packing the WAD!"
print "Everything is done!\nHave a nice day. :3"
sys.exit()

0
WiiPy/tools/__init__.py Normal file
View File

21
WiiPy/tools/wads.py Normal file
View File

@ -0,0 +1,21 @@
#----------------------------------------------------------------------
# WADd - a simple command line tool for packing and unpacking wads.
# (c) 2009 |Omega and #HACKERCHANNEL Productions.
#
# Wii.py (c) Xuzz, SquidMan, megazig, TheLemonMan, |Omega, and Matt_P.
#----------------------------------------------------------------------
import Wii, sys, os
if(len(sys.argv) < 2):
print "Usage: python wads.py <input> <output> ..."
sys.exit(0)
for i in range(1, len(sys.argv), 2):
if(os.isdir(sys.argv[i]):
elem = sys.argv[i]
elem2 = sys.argv[i + 1]
Wii.WAD.loadDir(elem).dumpFile(elem2)
else:
elem = sys.argv[i]
elem2 = sys.argv[i + 1]
Wii.WAD.loadFile(elem).dumpDir(elem2)

27
WiiPy/tools/wadtool.py Normal file
View File

@ -0,0 +1,27 @@
#----------------------------------------------------------------------
# Copyright (C) 2009 zc00gii
#
# Wii.py (c) Xuzz, SquidMan, megazig, TheLemonMan, |Omega, and Matt_P.
#----------------------------------------------------------------------
import os, sys, Wii
def wadpack(waddir, wadfile):
Wii.WAD.loadDir(waddir).dumpFile(wadfile)
print "WAD packed successfully"
def wadunpack(wadfile,waddir):
Wii.WAD.loadFile(wadfile).dumpDir(waddir)
print "WAD unpacked successfully"
if(len(sys.argv) < 4):
print "Usage: python wadtool.py [option] <input> <output>\nOptions:\n-u, --unpack Unpack your desired WAD file\n-p, --pack Pack your desired WAD file"
sys.exit(0)
doPackOrUnpack = sys.argv[1]
inputWad = sys.argv[2]
outputWad = sys.argv[3]
if doPackOrUnpack in ('-u','--unpack'):
wadunpack(inputWad, outputWad)
if doPackOrUnpack in ('-p','--pack'):
wadpack(inputWad, outputWad)

7
dependencies.txt Normal file
View File

@ -0,0 +1,7 @@
Dependencies:
Python 2.5 or higher
(Windows installer: )
PyQt4
(Windows installer: )
PyCrypto
(Windows installer: http://www.voidspace.org.uk/python/modules.shtml#pycrypto )

BIN
i18n/Qwad_ca.qm Normal file

Binary file not shown.

1003
i18n/Qwad_ca.ts Normal file

File diff suppressed because it is too large Load Diff

BIN
i18n/Qwad_de.qm Normal file

Binary file not shown.

1002
i18n/Qwad_de.ts Normal file

File diff suppressed because it is too large Load Diff

BIN
i18n/Qwad_en.qm Normal file

Binary file not shown.

1003
i18n/Qwad_en.ts Normal file

File diff suppressed because it is too large Load Diff

BIN
i18n/Qwad_es.qm Normal file

Binary file not shown.

1003
i18n/Qwad_es.ts Normal file

File diff suppressed because it is too large Load Diff

BIN
i18n/Qwad_fr.qm Normal file

Binary file not shown.

1002
i18n/Qwad_fr.ts Normal file

File diff suppressed because it is too large Load Diff

BIN
i18n/Qwad_it.qm Normal file

Binary file not shown.

1002
i18n/Qwad_it.ts Normal file

File diff suppressed because it is too large Load Diff

BIN
icons/gcqwadlogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
icons/qt4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
icons/wad.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
icons/wad.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

19
makeqwaddeb.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
#makeqwaddeb#
VERSION=$1
Sources=$(find | grep -v pyc$ | grep -v ui$ | grep -v ts$ | grep -v .pro$ | grep -v .qrc$ | grep -v bz2$ | grep -v dist | grep -v -w icons | grep -v ~$ | grep -v examinar | grep -v e4.$ | grep -v eric | grep -v makeqwaddeb)
cp -r GUI dist_debian/usr/share/Qwad/
cp -r wii_signer dist_debian/usr/share/Qwad/
cp -r i18n dist_debian/usr/share/Qwad/
cp Qwad.pyw dist_debian/usr/share/Qwad/
cp Qwad_rc.py dist_debian/usr/share/Qwad/
cp README.txt dist_debian/usr/share/Qwad/
cp CHANGELOG.txt dist_debian/usr/share/Qwad/
kwrite dist_debian/DEBIAN/control
rm dist_debian/DEBIAN/control~
dpkg --build dist_debian/ qwad-"$VERSION"_all.deb

3
qwad Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
cd /usr/share/Qwad
python Qwad.pyw $@