Search This Blog

Total Pageviews

Saturday, December 24, 2011

SharePoint Online Plans: Usage Rights

http://blog.mikehacker.net/2011/11/21/sharepoint-online-plans-usage-rights/



High-Level usage rights comparison across user subscriptions plans (12/21/2011)
Feature
Partner Access Plan
(external partners)
SharePoint Online Kiosk 1 and Kiosk 2
SharePoint Online E1 and E2
SharePoint Online E3 and E4
SharePoint Online Plan 1
SharePoint Online Plan 2
Can access all team sites by default?
No1
Yes
Yes
Yes
Yes
Yes
My Site
No
No
Yes
Yes
Yes
Yes
Enterprise Features (Access, Business Connectivity Services (BCS), InfoPath Forms, Excel and Visio Services)
Yes2
Yes3
No
Yes2
No
Yes2
Office Web Apps
View only
K1 – View only
K2 – View and edit
E1 – View only
E2 – View and edit
View and edit
View only
View only
Adds storage to the company’s overall pooled quota?
No
No
Yes. 500MB per user subscription license
Yes. 500MB per user subscription license
Yes. 500MB per user subscription license
Yes. 500MB per user subscription license
Can be an administrator of tenant, site or site collection?
No
No
Yes
Yes
Yes
Yes
1 – External partners can only access the sites they have been invited to by delegated site collection owners.
2 – Can view and upload Visio diagrams, view and build external lists, build and visit Access-based webpages, build and view embedded Excel graphs and create/publish, fill in and submit InfoPath forms.
3 – Kiosk workers have read-only rights except they can edit web-based and InfoPath Forms only.
For more detailed Microsoft licensing information, please visit the Product Use Rights (PUR) document page on the Microsoft Volume Licensing website.

Monday, December 19, 2011

SharePoint 2010 CSS Chart


SharePoint 2010 CSS Chart

CSS CommentsScreenshots
body #s4-ribboncont{background-image:none;} /*Globally turning off bordersThis is needed to have any of the style below to take effect.
.ms-cui-groupSeparator {border-right:1px solid #E7E7E8 !important; }.ms-cui-topBar2{border-width:0px;}*//*Turn on separators in the Ribbon
.ms-cui-ribbonTopBars{background: red url() repeat-x !important;
padding-top:0px;
}
/* Set the background for the tabs at the top (Browse / Page) */ms-cui-ribbonTopBars
.ms-cui-cg-i{background-image:url() !important;
background-position:bottom left;
background-repeat:no-repeat !important;
height:15px;
margin-bottom:2px;
}
.ms-cui-cg-db .ms-cui-cg-t{height:17px; background-image:url(‘http://integration.echn.ca/Media/SiteImages/bgBackground.gif’) !important; background-position:bottom right !important; background-repeat:no-repeat !important; margin-left:4px;}
.ms-cui-cg-t-i{ color:white; font-weight:bold; }
.ribbon-wrapper{position:relative;}
/* Set the background for the additional dynamic tabs (Web parts / Lists etc.) */
.fixed-ribbon{position:fixed; top:0; width:950px; z-index:21;}
.s4-title{height:34px; background: red url() repeat-x;
}
s4-title
.s4-title h1 a,.s4-title h2 a,.s4-title h2 {color: red;}
.s4-title .s4-pagedescription,.s4-title .s4uniqpermdescription {color:red;}s4-title-s4-pagedescription
.ms-cui-tt-s .ms-cui-tt-a {color:red !important;
background: red url();
}
.ms-cui-tabBody{background:red url();
}
/* Set the background of the Tab Body */
The next section changes the style one of the additional tools menu items. There are several in the Corev4 CSS to change.
.ms-cui-cg-db .ms-cui-cg-t{color: red;
background:url(“/_layouts/images/bgximg.png”) repeat-x -0px -834px;
}
/* Font color of the Library Tools and background using bgximg.png offset by -834px */
.ms-cui-cg-db .ms-cui-tt-a:hover {border-color: red;
border-top-color:red;
background:url(“/_layouts/images/bgximg.png”) repeat-x -0px -834px;
}
/*Borders and background of Library Tools when menu is not selected.
.ms-cui-cg-db .ms-cui-cg-i{border-color: red;}/* Border above library tools when not selected*/
.ms-cui-cg-db.ms-cui-cg-s .ms-cui-cg-i{border-color: red;}/* Border above library tools when sub-menu item selected*/
.ms-cui-cg-db.ms-cui-cg-s .ms-cui-ct-ul{background-color: red;
border-color: red;
}
/* Gap between menu items in the Library Tools when sub-menu item selected */
.ms-cui-cg-db.ms-cui-cg-s .ms-cui-cg-t{color: red;
background:url(“/_layouts/images/bgximg.png”) repeat-x -0px -834px;
}
/* Background of Library Tools when sub-menu item selected */
.ms-cui-cg-db .ms-cui-ct-first .ms-cui-tt-a{border-left-color: red;} .ms-cui-cg-db .ms-cui-ct-last .ms-cui-tt-a{border-left-color: red;}/*Borders of the Library Tools when Browse tab selected*/
.ms-cui-cg-db.ms-cui-cg-s .ms-cui-ct-first .ms-cui-tt-a{border-left-color: red;}/* Border color on the first sub-menu item when selected*/
.ms-cui-cg-db.ms-cui-cg-s .ms-cui-ct-last .ms-cui-tt-a{border-right-color: red;}/* Border color on the last sub-menu item when not selected*/
.ms-cui-cg-db.ms-cui-cg-s .ms-cui-tt-s .ms-cui-tt-a{border-left-color: red; border-right-color: red;}/* Border color on the last sub-menu item when it’s selected*/
.ms-cui-cg-db.ms-cui-cg-s .ms-cui-tt-a{border-color: red;
border-top-color:red;
background-color:red;
}
/*None selected sub-menu item*/
.ms-cui-cg-db.ms-cui-cg-s .ms-cui-tt-a:hover{background-color: red !important;
border-top-color: red;}
/*Library tools none selected sub-menu item on hover */
.ms-cui-cg-gr.ms-cui-cg-s .ms-cui-cg-t{

color:#0e400d;

background-color:red;

background-image:none;

}

.ms-cui-cg-gr .ms-cui-tt-a:hover{


border-color:#56c553;

border-top-color:#56c553;

background:red;

}

.ms-cui-cg-gr .ms-cui-tt-a:hover{


border-color:red;

border-top-color:red;

background:url(“/_layouts/images/bgximg.png”) repeat-x -0px
-832px;
}

.ms-cui-cg-gr .ms-cui-ct-last .ms-cui-tt-a{


border-right-color:red;

}

.ms-cui-cg-gr .ms-cui-ct-first .ms-cui-tt-a{


border-left-color:red;

}

.ms-cui-cg-gr.ms-cui-cg-s .ms-cui-cg-t{


color:#0e400d;

background-color:red;

background-image:none;

}

.ms-cui-cg-gr.ms-cui-cg-s .ms-cui-tt-a{


background-color:red;

border-color:#56c553;

border-top-color:#56c553;
}

.ms-cui-cg-gr.ms-cui-cg-s .ms-cui-tt-s .ms-cui-tt-a:hover{


border-color:#03a200;

background-color:red !important;
}

.ms-cui-cg-gr.ms-cui-cg-s .ms-cui-tt-a:hover{


background-color:red !important;

border-color:#56c553;

border-top-color:#56c553;
}

.ms-cui-cg-gr.ms-cui-cg-s .ms-cui-tt-s .ms-cui-tt-a{


border-left-color:red;

border-right-color:red;

}

.ms-cui-cg-gr.ms-cui-cg-s .ms-cui-ct-last .ms-cui-tt-a{


border-right-color:red;

}

.ms-cui-cg-gr.ms-cui-cg-s .ms-cui-ct-ul{


background-color:red;

border-color:#03a200;

}
/*Start of the Browse menu formatting.*/
.s4-tn {background:red url();}/*Menu Bar background*/
.s4-tn li.static > a:hover{/* [ReplaceColor(themeColor:"Accent1")] */ color:red;}/*Browse none selected menu items on hover */
.s4-toplinks .s4-tn a.selected:hover{color: red;}/*Color of selected menu item on hover event.*/
.s4-toplinks .s4-tn a.selected{border-color: red;
border-bottom-color: red;
border-top-color: red;
background-color: red;
}
/*Border and Background of selected menu item.*/
/*Start of the Main Area formatting.*/
body #s4-mainarea.s4-pr{background: red url();}/*Below the Ribbow half of the page.*/
.s4-ca.s4-ca-dlgNoRibbon{background: red url();}/*Behind the Main Content*/
body #s4-leftpanel-content{background: red url(); }/*Background of the Left Panel*/
.s4-specialNavLinkList{background: red url();}/*Background of the navigation link list on quicklaunch*/
body #s4-leftpanel-content{ padding:0px 0px 0px;
border:1px solid #ffffff;
border-top-width:0px;
border-right-width:1px;
border-bottom-width:0px;
border-left-width:1px;
}
/*Border of the quicklaunch*/

Thanks for the Useful Info Mark.

Ref Link http://sp2010notes.wordpress.com/sharepoint-2010-css-chart


Sunday, December 18, 2011

WinForm SharePoint List Item Editing Tool

Use the WinForm SharePoint List Item Editing Tool if you want to work with SharePoint lists in batch. Without the need to create additional datasheet views, you can use this tool from your workstation to add and remove columns to a grid view. You can paste data from Excel and perform other batch functions such as checking in a selection of documents or importing a batch of documents. If you have event receivers on a list that fire when an item is added or modified, this tool will allow you to suppress those events when working in batch mode.



Saturday, November 26, 2011

SharePoint Enable RMS Using Object Model

Step 1 Enable IRM on the farm

SPWebService svc = SPFarm.Local.Services.GetValue();
SPIrmSettings irmSettings = svc.IrmSettings;
irmSettings.IrmRMSEnabled = true;
//set true or false based on the situation
irmSettings.IrmRMSUseAD = true;
irmSettings.IrmRMSCertServer = "certificate server here";
irmSettings.IrmChanges = irmSettings.IrmChanges + 1;
svc.Update();



Step2 Set the IRM properties for a document library
SPSite site = new SPSite("http:////");
SPList spList = site.OpenWeb().Lists["list_name"];
SPFolder folder = spList.RootFolder;
spList.IrmEnabled = true; //corresponds to "Restrict permission to documents in this library on download"
// BELOW SET=2, RESET=0
folder.Properties["vti_irm_IrmPrint" ] = 2; // Allow users to print documents
folder.Properties["vti_irm_IrmVBA" ] = 2; // Allow users to access content programmatically
folder.Properties["vti_irm_IrmOffline" ] = 2; // Users must verify their credentials every nOfflineDays
spList.IrmReject = true; // do not allow users to upload documents that do not support IRM
spList.IrmExpire = true; //sto[ restricting permissions to documents in this library on expiry date
folder.Properties["vti_irm_IrmOfflineDays"] = nOfflineDays;
// integer representing number of days after which user needs to verify credentials
folder.Properties["vti_irm_IrmExpireDate" ] = dtExpire.ToString("r", CultureInfo.InvariantCulture);
// date on which to stop restricting IRM permissions to documents
folder.Properties["vti_irm_IrmTitle" ] = "Permission Policy Title";
folder.Properties["vti_irm_IrmDescription"] = "Permission Policy Description";
folder.Update();
spList.Update();

Tuesday, November 22, 2011

Add an existing site collection Group to sub site with modified Roles

OBJECTIVE

The site collection contains a group named “All Members” with “Contributor” privilege.
I want to add this group programmatically to a sub site and modify its roles from “Contributor” to “Read” without modifying the original group.

The following are the variables used in the code:
       -          site: the SPSite object of the site collection being used
-          web: the SPWeb object of the sub site you want to add the group to.

SOLUTION:
SPGroup group = site.RootWeb.SiteGroups["All Members"];
SPRoleAssignment roleAssignment = new SPRoleAssignment(group);
SPRoleDefinition roleDefinition = site.RootWeb.RoleDefinitions["Read"];
roleAssignment.RoleDefinitionBindings.Add(roleDefinition);
if (!web.HasUniqueRoleAssignments)
     web.BreakRoleInheritance(true);
web.RoleAssignments.Add(roleAssignment);

---------------------------------------------------------------------------

Working with Group: quick review:
      1)       BREAK INHERITANCE  
         2)       ADD NEW GROUP TO SITE COLLECTION 
         3)       ASSOCIATE THE NEW GROUP TO A WEB 
         4)       ASSIGNMENT OF THE ROLES
         5)       ADD USERS TO THE GROUP 
         6)       REMOVE ALL ROLES
     

1) BREAK INHERITANCE
if (!web.HasUniqueRoleAssignments)
            web.BreakRoleInheritance(true);

2) ADD NEW GROUP TO SITE COLLECTION:
web.SiteGroups.Add("MyNewGroup", web.AssociatedOwnerGroup, null"MyNewGroup description");

3) ASSOCIATE THE NEW GROUP TO A WEB:
web.AssociatedGroups.Add(group);
web.Update();

4) ASSIGNMENT OF THE ROLES:
SPGroup group = web.SiteGroups["MyNewGroup"];
SPRoleAssignment roleAssignment = new SPRoleAssignment(group);
SPRoleDefinition roleDefinition = site.RootWeb.RoleDefinitions["Read"];
roleAssignment.RoleDefinitionBindings.Add(roleDefinition);
web.RoleAssignments.Add(roleAssignment);

5) ADD USERS TO THE GROUP:
SPUser user = web.EnsureUser("domain\MyUser"); 
SPGroup group = web.Groups["MyNewGroup"];                        
if(user!=null && group!=null)
     group.AddUser(user);

6) REMOVE ALL ROLES:
SPRoleAssignmentCollection SPRoleAssColn = web.RoleAssignments;
for (int i = SPRoleAssColn.Count - 1; i >= 0; i--)
{
      SPRoleAssColn.Remove(i);
}     

Thursday, November 10, 2011

Start User Profile Synchronization Service through Powershell cmd


Function ConvertTo-UnsecureString

([System.Security.SecureString]$string)
   {
   $unmanagedString =

[System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUni

code($string)
    $unsecureString =

[System.Runtime.InteropServices.Marshal]::PtrToStringUni

($unmanagedString)
     

[System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode

($unmanagedString)
   
        return $unsecureString
     }


$syncMachine = Get-SPServer "sp2010dev"
$profApp = Get-SPServiceApplication | where {$_.Name -eq "User Profile

Service Application 1"}
$account = Get-Credential "localdev\spfarm"
if ($syncMachine.Address -eq $env:ComputerName) {
    $syncSvc = Get-SPServiceInstance -Server $env:ComputerName | where

{$_.TypeName -eq "User Profile Synchronization Service"}
    $syncSvc.Status =

[Microsoft.SharePoint.Administration.SPObjectStatus]::Provisioning
    $syncSvc.IsProvisioned = $false
    $syncSvc.UserProfileApplicationGuid = $profApp.Id
    $syncSvc.Update()
    $profApp.SetSynchronizationMachine($syncMachine.Address,

$syncSvc.Id, $account.UserName, (ConvertTo-UnsecureString

$account.Password))
}

if ($syncSvc.Status -ne "Online") {
    Write-Host "Starting User Profile Synchronization Service..."
    Start-SPServiceInstance $syncSvc
}
do {Start-Sleep 2} while ((Get-SPServiceInstance -Server

$env:ComputerName | where {$_.TypeName -eq "User Profile

Synchronization Service"}).Status -ne "Online")

Start User Profile Synchronization Service through Powershell cmd


Function ConvertTo-UnsecureString

([System.Security.SecureString]$string)
   {
   $unmanagedString =

[System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUni

code($string)
    $unsecureString =

[System.Runtime.InteropServices.Marshal]::PtrToStringUni

($unmanagedString)
     

[System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode

($unmanagedString)
   
        return $unsecureString
     }


$syncMachine = Get-SPServer "sp2010dev"
$profApp = Get-SPServiceApplication | where {$_.Name -eq "User Profile

Service Application 1"}
$account = Get-Credential "localdev\spfarm"
if ($syncMachine.Address -eq $env:ComputerName) {
    $syncSvc = Get-SPServiceInstance -Server $env:ComputerName | where

{$_.TypeName -eq "User Profile Synchronization Service"}
    $syncSvc.Status =

[Microsoft.SharePoint.Administration.SPObjectStatus]::Provisioning
    $syncSvc.IsProvisioned = $false
    $syncSvc.UserProfileApplicationGuid = $profApp.Id
    $syncSvc.Update()
    $profApp.SetSynchronizationMachine($syncMachine.Address,

$syncSvc.Id, $account.UserName, (ConvertTo-UnsecureString

$account.Password))
}

if ($syncSvc.Status -ne "Online") {
    Write-Host "Starting User Profile Synchronization Service..."
    Start-SPServiceInstance $syncSvc
}
do {Start-Sleep 2} while ((Get-SPServiceInstance -Server

$env:ComputerName | where {$_.TypeName -eq "User Profile

Synchronization Service"}).Status -ne "Online")

Tuesday, November 1, 2011

Get All SubWebs using Client Object Model


  static string mainpath = "http://triad102:1001";
        static void Main(string[] args)
        {

            getSubWebs(mainpath);
            Console.Read();
        }

        public static  void  getSubWebs(string path)
        {
         
            try
            {
                ClientContext clientContext = new ClientContext( path );
                Web oWebsite = clientContext.Web;
                clientContext.Load(oWebsite, website => website.Webs, website => website.Title);
                clientContext.ExecuteQuery();
                foreach (Web orWebsite in oWebsite.Webs)
                {
                    string newpath = mainpath + orWebsite.ServerRelativeUrl;
                    getSubWebs(newpath);
                    Console.WriteLine(newpath + "\n" + orWebsite.Title );
                }
            }
            catch (Exception ex)
            {
               
            }
         
         
        }

Monday, October 31, 2011

Joins in SharePoint COM


private void GetParts(string searchSku)
{
  Parts.Clear();
  List partsList = clientContext.Web.Lists.GetByTitle("Parts");
  List inventoryLocationsList = 
    clientContext.Web.Lists.GetByTitle("Inventory Locations");

  CamlQuery camlQueryPartsList = new CamlQuery();
  camlQueryPartsList.ViewXml =
    @"<View>
        <Query>
          <Where>
            <BeginsWith>
              <FieldRef Name='SKU' />
              <Value Type='Text'>" + searchSku + @"</Value>
            </BeginsWith>
          </Where>
        </Query>
      </View>";

  CamlQuery camlQueryInvLocationList = new CamlQuery();
  camlQueryInvLocationList.ViewXml = 
    @"<View>
        <Query>
          <Where>
            <BeginsWith>
              <FieldRef Name='PartLookupSKU' />
              <Value Type='Lookup'>" + searchSku + @"</Value>
            </BeginsWith>
          </Where>
          <OrderBy Override='TRUE'>
            <FieldRef Name='PartLookupSKU' />
          </OrderBy>
        </Query>
        <ViewFields>
          <FieldRef Name='PartLookup' LookupId='TRUE' />
          <FieldRef Name='PartLookupSKU' />
          <FieldRef Name='PartLookupTitle' />
          <FieldRef Name='PartLookupDescription' />
          <FieldRef Name='BinNumber' />
          <FieldRef Name='Quantity' />
        </ViewFields>
        <ProjectedFields>
          <Field Name='PartLookupSKU' Type='Lookup' List='PartLookup'                    
                 ShowField='SKU' />
          <Field Name='PartLookupTitle' Type='Lookup' List='PartLookup' 
                 ShowField='Title' />
          <Field Name='PartLookupDescription' Type='Lookup' List='PartLookup' 
                 ShowField='PartsDescription' />
        </ProjectedFields>
        <Joins>
          <Join Type='LEFT' ListAlias='PartLookup'>
          <!--List Name: Parts-->
            <Eq>
              <FieldRef Name='PartLookup' RefType='ID' />
              <FieldRef List='PartLookup' Name='ID' />
            </Eq>
          </Join>
        </Joins>
      </View>";

  partListItems = partsList.GetItems(camlQueryPartsList);
  inventoryLocationListItems = 
    inventoryLocationsList.GetItems(camlQueryInvLocationList);
  
  clientContext.Load(partListItems);
  clientContext.Load(inventoryLocationListItems);
  clientContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed);
}


Saturday, October 29, 2011

Get ALL ListNames through Client object Model


ClientContext clientContext =
            new ClientContext("http://intranet.contoso.com");
        ListCollection listCollection = clientContext.Web.Lists;
        clientContext.Load(
            listCollection,
            lists => lists
                .Include(
                    list => list.Title,
                    list => list.Hidden)
                . Where(list => ! list.Hidden)
             );
        clientContext.ExecuteQuery();
        foreach (var list in listCollection)
            Console.WriteLine(list.Title);

Client Object Model Sample

Get All List Items :
ClientContext clientContext = new ClientContext("http://intranet.contoso.com");
 List list = clientContext.Web.Lists.GetByTitle("Announcements");
 CamlQuery camlQuery = new CamlQuery();
 camlQuery.ViewXml = "<View/>";
 ListItemCollection listItems = list.GetItems(camlQuery);
 clientContext.Load(list);clientContext.Load(listItems);
 clientContext.ExecuteQuery();
 foreach (ListItem listItem in listItems)
 Console.WriteLine("Id: {0} Title: {1}", listItem.Id, oListItem["Title"]);
Creating List using COM, Add Fields and populate Data:
ClientContext clientContext =
            new ClientContext("http://intranet.contoso.com");
        Web site = clientContext.Web;

        // Create a list.
        ListCreationInformation listCreationInfo =
            new ListCreationInformation();
        listCreationInfo.Title = "Client API Test List";
        listCreationInfo.TemplateType = (int)ListTemplateType.GenericList;
        List list = site.Lists.Add(listCreationInfo);

        // Add fields to the list.
        Field field1 = list.Fields.AddFieldAsXml(
            @"<Field Type='Choice'
                     DisplayName='Category'
                     Format='Dropdown'>
                <Default>Specification</Default>
                <CHOICES>
                  <CHOICE>Specification</CHOICE>
                  <CHOICE>Development</CHOICE>
                  <CHOICE>Test</CHOICE>
                  <CHOICE>Documentation</CHOICE>
                </CHOICES>
              </Field>",
            true, AddFieldOptions.DefaultValue);
        Field field2 = list.Fields.AddFieldAsXml(
            @"<Field Type='Number'
                     DisplayName='Estimate'/>",
            true, AddFieldOptions.DefaultValue);

        // Add some data.
        ListItemCreationInformation itemCreateInfo =
            new ListItemCreationInformation();
        ListItem listItem = list.AddItem(itemCreateInfo);
        listItem["Title"] = "Write specs for user interface.";
        listItem["Category"] = "Specification";
        listItem["Estimate"] = "20";
        listItem.Update();

        listItem = list.AddItem(itemCreateInfo);
        listItem["Title"] = "Develop proof-of-concept.";
        listItem["Category"] = "Development";
        listItem["Estimate"] = "42";
        listItem.Update();
        
        listItem = list.AddItem(itemCreateInfo);
        listItem["Title"] = "Write test plan for user interface.";
        listItem["Category"] = "Test";
        listItem["Estimate"] = "16";
        listItem.Update();

        listItem = list.AddItem(itemCreateInfo);
        listItem["Title"] = "Validate SharePoint interaction.";
        listItem["Category"] = "Test";
        listItem["Estimate"] = "18";
        listItem.Update();

        listItem = list.AddItem(itemCreateInfo);
        listItem["Title"] = "Develop user interface.";
        listItem["Category"] = "Development";
        listItem["Estimate"] = "18";
        listItem.Update();

        clientContext.ExecuteQuery();
http://www.codeproject.com/KB/sharepoint/SP2010ClientObjectModel.aspx

Users AD Browser Webpart

Thursday, October 13, 2011

SharePoint 2010 News Rotator

Using the SharePoint 2010 Silverlight Client Object Model and Excel Services REST API

SharePoint Multiple files Download as zip file

SharePoint Multiple files Download as zip file


The user has selected some documents and a sub-folder so my custom ribbon button is enabled:

The user clicks on this button and this feature executes and after it’s complete the user is prompted with this (note, the filename is a timestamp):

The user saves it down locally to his computer and sees all the files are there:
WSP file (Site collection feature): DeviantPoint.DownloadZip.wsp (84.84 kb)
Visual Studio 2010 Project file: DeviantPoint.DownloadZip.zip (317.01 kb)




Exchange WebPart for SharePoint 2010

"Take a picture" Field for SharePoint 2010