Photo-Illustration: Curbed; Photos: Ashley Allen, Charlie Dulik
Photo-Illustration: Curbed; Photos: Ashley Allen, Charlie Dulik
Photo-Illustration: Curbed; Photos: Ashley Allen, Charlie Dulik
Viola Straker and her neighbors in her 31-unit Crown Heights building have a proposal to end the yearslong standoff over who owns 1074 Eastern Parkway: Sell the building to them. “Tenants would be better off purchasing instead of selling it to another slumlord,” she says.
The idea might sound outlandish: Straker lives on Social Security, giving her just enough to pay her stabilized monthly rent of $817, to say nothing of trying to purchase a multifamily building valued at over $1.3 million. After her landlord died in 2017 and previous agreements with another company to manage the building fell through, it also needs expensive repairs, with leaks, mold, pests everywhere, and a collapsing roof. But what if tenants didn’t have to be rich to buy their building?
Straker and her neighbors could get enough resources to buy and even fix their building if new legislation passes in Albany. It’s called the Tenant Opportunity to Purchase Act (TOPA), which offers New York residents a number of tools to buy their rental buildings, and it’s gaining support in the state legislature after being introduced by State senator Zellnor Myrie and State assemblywoman Marcela Mitaynes.
The bill is modeled after a law of the same name that’s been in effect since 1980 in Washington, D.C., as well as a 2019 version in San Francisco called the Community Opportunity to Purchase Act. In a nutshell, TOPA grants tenants the first right to purchase their building if a landlord lists it or receives a credible offer from another buyer. Tenants can also choose how to purchase a building: They can turn it into a co-op, or assign their rights to a new landlord to keep it as a rental building.
But that’s just the start. Because many lenders consider affordable housing to be too risky, New York’s TOPA bill would create a pool of funding to help tenants buy their building, and staff up housing agencies to help tenants through the process. It would also give tenants as long as nine months to submit a statement of interest, form a tenants’ association, propose an offer, and secure financing, during which time the landlord wouldn’t be able to sell to any other party. The goal is to deter speculative flipping, and keep buildings in the hands of the people who actually call them home.
Both Mitaynes, who represents Sunset Park, and Zellnor, who represents Crown Heights, say that TOPA would protect their working-class constituents from being displaced. A spokesman for Zellnor said, “We’re facing a housing crisis and a historic exodus of Black people from Brooklyn — TOPA would go a long way toward reversing those trends.”
Ramon Jacobson has helped tenants finance TOPA purchases for nearly 25 years, as director of the D.C. office of the nonprofit Local Initiatives Support Corporation (LISC). He’s seen it turn around neglected properties and give renters a pathway to homeownership. City stats show that there have been 25 buildings converted under TOPA over the last five years. “So many landlords are just passive investors, like, ‘My accountant collects payments every month, my property manager fixes it,’ and they haven’t been there for twenty years.” When those landlords finally move on, even tenants who have no interest in ownership can sell their purchasing rights to another buyer, and “get some slice of the pie,” he says. But if they decide to buy the building, or assign their rights to a nonprofit like LISC to run the building as affordable housing, “the tenants get a home where they can bake a whole pie, and sit down and eat it.”
New York’s version of TOPA would be stricter than D.C.’s: tenants wouldn’t be able to sell their homeownership rights to anyone. And unlike in D.C., where tenants have the option to assign their rights to for-profit developers, New York’s version would only allow tenants to assign their rights to a nonprofit or public housing provider. New York’s bill also includes an affordability requirement, unlike D.C.’s law: that all future maintenance, rent, and sale prices would need to be affordable to someone making 80 percent of the area median income.
Historically, New York City has created resident-owned housing through the HDFC program, a framework for limited-equity co-ops created in the 1980s. Back then, the city sold off abandoned and foreclosed buildings for as little as $250 to residents who converted them to co-ops with rules that strictly limited resale profits, and only considered offers from prospective buyers below a certain income. There were obvious benefits to this; keeping buildings affordable produces good housing. A 2022 LISC report found that New York City multifamily properties receiving affordability subsidies had far fewer maintenance violations than buildings bought by speculators with high levels of debt.
But there are far fewer ways to create HDFC co-ops today, says Arielle Hersh, an organizer with the Urban Homesteading Assistance Board (UHAB), a nonprofit that specializes in these conversions. Much of that is simply because buildings cost a lot more. Tenants trying to buy their own building would have to negotiate with their landlord and secure enough financing to not only outbid well-capitalized developers, but also to renovate the building afterward. Then, they would have to find some way to keep their monthly fees affordable while paying off their loans: a daunting task.
The chance of success goes up if tenants have three things: organization, funding, and a way to stall. That’s basically what TOPA tries to provide. Last year, Hersh helped a group of Bronx tenants purchase their own building, who learned some lessons that they think could guide others. The process started in 2017, when their aging rent-stabilized walkup at 700 East 134th Street was bought by a landlord named James Giddings. Giddings, a commercial landlord who acquired the 21-unit building at a discount after the previous landlord declared bankruptcy, claimed the building had been deregulated and hiked their rents up by as much as $500, despite worsening conditions there. The tenants disputed the increase with the Department of Housing and Community Renewal, but the case languished.
In 2019, a housing organizer introduced the residents to Hersh and the UHAB board, who told them it might be possible to buy their building if the nonprofit helped with funding. But Giddings wouldn’t entertain an offer from them — at least, not until the pandemic threw the housing market into turmoil and tied up the court cases. That pending DHCR case suddenly became an albatross, says Claudia Waterton, one of the tenant leaders, who has lived in a studio at the Bronx building for nearly ten years. “It was like the one hold we had. No developer would touch it until that case was closed.”
The delay was like having TOPA rights: an extended time period during which the landlord couldn’t find buyers on the open market. That gave UHAB enough time to line up a sizable bridge loan from an anonymous donor, and with the offer in front of him, Giddings finally relented. Last February, the nonprofit officially bought the building on behalf of the tenants for $2.6 million — well below the $4 million Giddings claimed he had paid for it.
The process isn’t over. Waterton, who works at a printing company, and her neighbors, who include a chef and a nurse as well as people who were formerly homeless, now have to fix up the building. Hersh estimates the repairs will cost around $650,000 — which means applying for more funding from a hodgepodge of sources, from city grants to the U.S. Department of Energy’s Weatherization Assistance Program. UHAB also has to replace its bridge loan with permanent financing before it can formally hand over the building to the residents. The goal is to get a HUD loan for affordable housing — but that’s been affected by ballooning interest rates. “It has not been fun to watch those numbers climb in the last year,” says Hersh.
Currently Waterton pays a monthly rent of $1050, and the highest rent in the building is $1550. When they finally convert the building into a co-op, tenants will be able to buy their units for $2,500, and she hopes the monthly fees will remain affordable: “We’re trying to stay in the $1,250 to 13-something range; we’re trying not to go too crazy.”
All of this would be easier with TOPA, she says. For one, it would have given them the right to redetermine the purchase price through an independent third-party appraisal, something Waterton thinks would’ve saved them money and brought their price down from the $2.6 million they paid.
Even more importantly, TOPA would have given them easier access to financing. The bill’s supporters are proposing a revolving “TOPA Acquisition Fund” to reach $1 billion over the next four years, that would be loaned to successful TOPA applicants via community development finance institutions. In that time, the money could convert an estimated 6,800 units of permanently affordable, resident-controlled housing, advocates say. By comparison, data from D.C.’s Department of Housing and Community Development shows their TOPA law, with a roughly $112 million revolving fund, has converted 1,928 affordable units over the last five years — though many of those conversions also had the help of private financing, says LISC’s Jacobson.
Housing advocates who have been working with the bill’s sponsors are confident that it will be included in the budgets submitted by the State Assembly and State Senate in coming weeks, though it’s not yet clear if the Senate version will include the $1 billion funding request. Would TOPA mean anything without that money? “It would establish a really strong right for tenants to organize in their building,” Hersh says, but she concedes that “it would be much harder to do a successful TOPA conversion” without the financing. And like D.C.’s law, even the funded version of New York’s TOPA would not provide permanent financing — Hersch imagines residents would have to seek a mix of public and private loans to pay back their initial acquisition loan and make repairs, as the tenants of 700 East 134th are doing. This can be a stumbling block for TOPA conversions, Jacobson says. Buildings often have expensive repair needs after the purchase, and insufficient financing at this stage can leave residents in a kind of “limbo.”
New York’s real estate industry is just starting to learn about the bill — and most are skeptical, if not disdainful, of it. Ann Korchak, the director of the Small Property Owners of New York, says “it sounds like another complicated government operation; it’s hard to see how a process like this works.” John Stewart, an associate broker at Marcus & Millichap, says the bill doesn’t seem practical: “Buying a building requires some focus and guidance. It’s not a committee of 20 tenants that’s going to be nimble enough to buy a building and make decisions. It’d be like herding cats.” He’s particularly concerned about the time period that TOPA would give tenants to purchase buildings: “It would make the purchase and sale of buildings grind to a halt, essentially.”
Jay Martin, the executive director of the Community Housing Improvement Program, a landlord organization currently involved in a lawsuit to strike down a 2019 rent stabilization law, says he isn’t opposed to TOPA (“Adding new buyers to the market is good for someone selling”), but thinks the bill would be meaningless if it isn’t backed by substantial funding. Like Stewart, he’s leery of the time period they’ll be given — more than six months would be “getting a little ridiculous,” he says. “There’s a strong argument to say the valuation of the building could deteriorate during that time.”
Assuming TOPA makes it into the budget in coming days, it’ll be up to Governor Kathy Hochul to decide how to respond. Advocates familiar with the budget negotiations say she’s open to it, and that’s a good sign. Waterton traveled to Albany last week to testify at a hearing in support of the bill: “I want all tenants who are organizing in their buildings like I did to have the same opportunity to purchase their building and take control,” she told a panel of legislators.
For Straker, the Crown Heights tenant, that would mean finally getting the repairs they need. But she also envisions doing much more: making their building as elegant as the co-op next door: “It looks really good. There’s a nice garden in the front with roses, and nice cobblestones,” she says.
For the Bronx residents who are in the middle of this process, co-op ownership has already made a difference. Recently, Waterton and her neighbors did something they never would’ve been able to do previously: They fired their new property managers for being too slow to make repairs. “I don’t like firing people, but we weren’t happy,” Waterton says. And the experience was empowering: “How many tenants could say they can do that?” She has a new title, too: president of the board. It’s a lot of unpaid work, but “I love doing it,” she says. “I’m making a place that not only I can call home, but that my neighbors can call home too. And this is just the start. One day, we’re going to look back on this and be like, Oh, that didn’t seem so hard.”
By submitting your email, you agree to our
Terms and Privacy Notice
and to receive email correspondence from us. This site is protected by reCAPTCHA and the Google
Privacy Policy and
Terms of Service apply.
or
Already a subscriber?
What is your email?
This email will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
Password must be at least 8 characters and contain:
Lower case letters (a-z)
Upper case letters (A-Z)
Numbers (0-9)
Special Characters (!@#$%^&*)
This password will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
You’re in!
As part of your account, you’ll receive occasional updates and offers from New York, which you can opt out of anytime.
or
Already a subscriber?
What is your email?
This email will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
Password must be at least 8 characters and contain:
Lower case letters (a-z)
Upper case letters (A-Z)
Numbers (0-9)
Special Characters (!@#$%^&*)
This password will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
You’re in!
As part of your account, you’ll receive occasional updates and offers from New York, which you can opt out of anytime.
Already a subscriber?
Already a subscriber?
`;
// integrate Sub(x) scripts and elements
if (hostname !== 'subs.nymag.com') { // do not integrate on this subdomain
document.head.appendChild(trackingScript);
document.body.insertAdjacentHTML('beforeend', subXAnimationElements);
}
There was an error processing the request. Please try again later."}).catch(e=>console.error("Error verifying email: ",e)))(r.querySelector(".content"),o.bannerCTAVerification)})):(l.remove(),s.remove()),o.dismissable||n.remove(),o.useAlertIcon||a.remove(),r.classList.add("show"),n.addEventListener("click",()=>{u(),r.classList.remove("show")})}else r.remove()}});
}, {"1":1,"6":6,"12":12,"35":35,"40":40}];
window.modules["global-nav.client"] = [function(require,module,exports){"use strict";const dom=require(4),auth=require(12),signInButton=dom.find(".user-signin"),signOutButton=dom.find(".user-signout"),globalNav=dom.find('[class^="global-nav"]'),body=dom.find("body"),dropdownItems=dom.findAll(".dropdown-wrap"),gtm=require(1),appendLandingPageParams=require(135),pageUri=require(124).getPageUri(),subscriptionPromoLinks=dom.findAll(".persist-params"),searchString=window.location.search||"";function closeDropdowns(e){let n=globalNav.querySelectorAll(".dropdown.open");dropdownItems.forEach(function(t){let o=t.querySelector(".dropdown");!n||t.contains(e.target)&&27!==e.keyCode||o.classList.remove("open")})}function gtmSendReport(e,n,t){let o={eventCategory:"ecommerce",eventAction:"componentClick",brand:e,dimension23:"global-nav",list:pageUri,pageZone:"header",variant:"nav-link"};"global-nav-link"===t&&(o.eventLabel=n.href),gtm.reportNow(o)}function updateElementTargetUrlsIfQueryStrings(e){if(searchString){const n=new URLSearchParams(searchString);let t=e.href;if(t.includes("?")){const o=t.split("?"),i=new URLSearchParams(o[1]);for(let e of n.entries())i.set(e[0],e[1]);t=`${o[0]}?${i.toString()}`,e.href=t}else e.href=`${t}?${n.toString()}`}}function init(e){const n=e.querySelectorAll(".to-landing-page");window.addEventListener("auth:init",()=>{signInButton.addEventListener("click",function(e){e.preventDefault(),auth.showEmbeddedLoginFlow("top navigation")}),signOutButton.addEventListener("click",function(e){e.preventDefault(),gtmSendReport("Sign Out",e.target,"user-info-link"),auth.logout()}),auth.isAuthenticated()&&e.classList.add("signed-in"),auth.isSubscriber()&&e.classList.add("subscribed"),e.querySelectorAll(".user-link").forEach(e=>{e.classList.add("active")}),subscriptionPromoLinks.forEach(e=>{updateElementTargetUrlsIfQueryStrings(e)}),appendLandingPageParams(n)})}dropdownItems.forEach(function(e){e.addEventListener("click",function(){e.querySelector(".dropdown").classList.toggle("open")})}),body.addEventListener("click",closeDropdowns),document.addEventListener("keydown",closeDropdowns),globalNav.addEventListener("click",function(e){let n=e.target;n.classList.contains("global-nav-track")&>mSendReport(n.text,n,"global-nav-link")}),module.exports=init;
}, {"1":1,"4":4,"12":12,"124":124,"135":135}];
window.modules["aaa-module-mounting.legacy"] = [function(require,module,exports){"use strict";const _pickBy=require(221),_each=require(406),Fingerprint2=require(408),DS=require(407),Eventify=require(246);function registerGlobals(){window.DS=DS,window.Eventify=Eventify,window.Fingerprint2=Fingerprint2,DS.value("Eventify",Eventify),DS.value("Fingerprint2",Fingerprint2),DS.value("$document",window.document),DS.value("$window",window)}function mountDollarSliceComponents(){DS.service("components",["$document","$module",function(e,n){var o=_pickBy(n.definitions,e=>e.providerStrategy===n.providers.controller),r=Object.keys(o);function t(e){return o=>{try{n.get(e,o)}catch(e){logMountError(o,e)}}}_each(r,n=>{var o=e.querySelectorAll('[data-uri*="/_components/'+n+'/"]'),r=e.querySelectorAll('[data-uri$="/_components/'+n+'"]');_each(o,t(n)),_each(r,t(n))}),this.components=r}]),DS.get("components")}function logMountError(e,n){const o=e.outerHTML.slice(0,e.outerHTML.indexOf(e.innerHTML));console.error("Error attaching controller to "+o,n)}registerGlobals(),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{mountDollarSliceComponents()}):mountDollarSliceComponents();
}, {"221":221,"246":246,"406":406,"407":407,"408":408}];
window.modules["ads.legacy"] = [function(require,module,exports){"use strict";const _map=require(118),_forEach=require(107),_isString=require(268),_intersectionWith=require(409),_isEqual=require(274),_each=require(406),_debounce=require(182),_sortBy=require(205),page=require(124),visit=require(114);DS.service("adService",["Eventify","$cid","$document","$window",function(e,t,a,i){var o,n,s,r,d,c,u,l,g={},p=this,h=[],f=visit.getQueryParamsObject(["utm_campaign"]),m=document.querySelector('script[data-type="ad-a9"]'),b=[],w=!1,v=[],y=document.querySelector('script[data-name="ad-doubleverify"]');document.querySelector('script[data-name="concert-ads"]')||(i.NYM={},i.NYM.analytics={},i.NYM.analytics.adStartTime=i.performance.now(),i.googletag=i.googletag||{},i.googletag.cmd=i.googletag.cmd||[],u=i.googletag,(m||y)&&(i.googletag.cmd=i.googletag.cmd||[],i.googletag.cmd.push(function(){i.googletag.pubads().disableInitialLoad()})),m&&(l=i.setInterval(function(){void 0!==window.apstag&&void 0!==window.apstag.timeout&&(i.clearInterval(l),window.apstag.cleared=!0,l=null)},10),setTimeout(function(){l&&(i.clearInterval(l),i.googletag.pubads().refresh(),window.apstag||console.log("MESSAGE: Timeout for A9 load exceeded, aborting"))},500)),y&&(b.push(new Promise(function(e){w?e():v.push(e)})),c=i.setTimeout(T,2500)),o=function(e){var t,a,o=e.data,n=[];return o.loaded?e:(o.loaded=!0,t=null,(t=o.sizes?u.defineSlot(o.name,o.sizes,o.id).addService(u.pubads()):u.defineOutOfPageSlot(o.name,o.id).addService(u.pubads())).setTargeting("adid",o.id),f.hasOwnProperty("utm_campaign")&&t.setTargeting("utmcamp",f.utm_campaign),a=p.getAdCount(o.label),t.setTargeting("label",o.label+"_"+o.site+"-"+a),u.display(o.id),u.pubads().addEventListener("slotOnload",function(){i.NYM.analytics.firstAdLoadTime||(i.NYM.analytics.firstAdLoadTime=i.performance.now(),i.NYM.analytics.firstAdLoadLabel=e.data.label)}),n=_(o),Promise.all(b).then(function(){n?window.apstag&&window.apstag.cleared?window.apstag.fetchBids({slots:[n],timeout:window.apstag.timeout},function(){u.cmd.push(function(){window.apstag.setDisplayBids(),u.pubads().refresh([t],{changeCorrelator:!1})})}):y&&u.pubads().refresh([t],{changeCorrelator:!1}):u.pubads().refresh([t],{changeCorrelator:!1})}),e.slot=t,e)},n=function(e){var a,i,o,n=t(),s=e.getAttribute("data-name"),r=e.getAttribute("data-sizes"),d=e.getAttribute("data-label"),c=e.getAttribute("data-site");n=e.id,r&&r.length?(r=r.split(","),a=[],_map(r,function(e){e=e.split("x"),i=parseInt(e[0]),o=parseInt(e[1]),a.push([i,o])})):(e.classList.add("oop"),a=!1),this.data={id:n,name:s,sizes:a,loaded:!1,label:d,site:c},g[n]=this},r=function(e){u.cmd.push(function(){var t=o(e);g[e.data.id]=t})},s=function(e){var t=[];e.slot?(t=_(e))&&window.apstag&&window.apstag.cleared&&window.apstag.fetchBids({slots:[t],timeout:window.apstag.timeout},function(){u.cmd.push(function(){window.apstag.setDisplayBids(),u.pubads().refresh([e.slot],{changeCorrelator:!1})})}):e&&r(e)},u.cmd.push(function(){var e,t,o,n=page.getMeta("article:tag"),s=page.getMeta("author"),r=i.location.href,d=(e=a.head.querySelector(".head-gtm"),t=a.body.querySelector(".gtm"),e&&"top"===e.getAttribute("data-gtm")?"gtmtop":t&&"bottom"===t.getAttribute("data-gtm")?"gtmbottom":"");o=[],_forEach([n,s,d],function(e){_forEach(e.split(","),function(e){(e=e.trim().toLowerCase().replace(/\s/g,"-").replace(/\'|\’/g,"")).length&&o.push(e)})}),u.pubads().setTargeting("kw",o),u.pubads().setTargeting("entry_group",o),r=r.slice(r.lastIndexOf("/")+1),u.pubads().setTargeting("pn",r),u.companionAds().setRefreshUnfilledSlots(!0),u.pubads().enableAsyncRendering(),u.enableServices()}),this.load=r,this.create=function(e){return new n(e)},this.refresh=function(e){var t;_isString(e)?(t=this.getById(e),s(t)):s(e)},this.remove=function(e){var t=e.data.id;a.getElementById(t).innerHTML=""},this.getAdCount=function(e){var t,a=0,i=Object.keys(g);return _each(i,function(i){(t=g[i]).data.loaded&&t.data.label===e&&a++}),a},this.getById=function(e){return g[e]},d=_debounce(function(){var e={TopLeaderboard:1,RightColTopMPU:2,outOfPage:99,"homepageTakeover/TopLeaderboard":1},t=_sortBy(h,function(t){return e[t.data.label]||10});_forEach(t,function(e){return e.data.sizes?r(e):i.setTimeout(function(){r(e)},2e3)}),y&&window.PQ.cmd.push(()=>{try{window.PQ.loadSignals(["ids","bsc","vlp"],T)}catch(e){T(),console.error(`There has been an error loading Double Verify signals: ${e}`)}}),h=[]},10),this.addToPageLoadQueue=function(e){h.push(e),d()});function _(e){var t,a=e.sizes;return a=_intersectionWith(a,[[970,250],[970,90],[728,90],[300,600],[300,250],[320,100],[320,50]],_isEqual),e.sizes&&e.sizes.length&&(t={slotID:e.id,sizes:a,slotName:e.label}),t}function T(){i.clearTimeout(c),w=!0,_forEach(v,function(e){e()})}}]);
}, {"107":107,"114":114,"118":118,"124":124,"182":182,"205":205,"268":268,"274":274,"406":406,"409":409}];
window.modules["cid.legacy"] = [function(require,module,exports){"use strict";DS.service("$cid",function(){var r=Math.floor(100*Math.random());return function(){return"cid-"+ ++r}});
}, {}];
window.modules["client.legacy"] = [function(require,module,exports){"use strict";require("cid.legacy"),require("ads.legacy"),require("facebook.legacy"),require("aaa-module-mounting.legacy");
}, {"cid.legacy":"cid.legacy","ads.legacy":"ads.legacy","facebook.legacy":"facebook.legacy","aaa-module-mounting.legacy":"aaa-module-mounting.legacy"}];
window.modules["facebook.legacy"] = [function(require,module,exports){"use strict";DS.service("facebook",[function(){this.fb=function(i){window.FB&&window.FB[i].apply(this,Array.prototype.slice.call(arguments,1))}}]);
}, {}];
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o typeof key === 'string' && key.match(/\.legacy$/)).forEach(key => window.require(key));
}
function tryToMount(fn, el, name) {
try {
fn(el); // init the controller
} catch (e) {
const elementTag = el.outerHTML.slice(0, el.outerHTML.indexOf(el.innerHTML));
console.error(`Error initializing controller for "${name}" on "${elementTag}"`, e);
}
}
/**
* mount client.js component controllers
*/
function mountComponentModules() {
Object.keys(window.modules).filter(key => typeof key === 'string' && key.match(/\.client$/)).forEach(key => {
let controllerFn = window.require(key);
if (typeof controllerFn === 'function') {
const name = key.replace('.client', ''),
instancesSelector = `[data-uri*="_components/${name}/"]`,
defaultSelector = `[data-uri$="_components${name}"]`,
instances = document.querySelectorAll(instancesSelector),
defaults = document.querySelectorAll(defaultSelector);
for (let el of instances) {
tryToMount(controllerFn, el, name);
}
for (let el of defaults) {
tryToMount(controllerFn, el, name);
}
}
});
}
// Make sure that a `window.process.env.NODE_ENV` is available in the client for any dependencies,
// services, or components that could require it
// note: the `` value is swapped for the actual environment variable in /lib/cmd/compile/scripts.js
window.process = window.process || {};
window.process.env = window.process.env || {};
if (!window.process.env.NODE_ENV) {
window.process.env.NODE_ENV = '';
}
// note: legacy controllers that require legacy services (e.g. dollar-slice) must
// wait for DOMContentLoaded to initialize themselves, as the files themselves must be mounted first
mountLegacyServices();
mountComponentModules();
// ]]